summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorvictorfisac <[email protected]>2016-10-06 20:57:31 +0200
committervictorfisac <[email protected]>2016-10-06 20:57:31 +0200
commit2a158c47955d2d849e939152e0c174b02c500104 (patch)
treefbf515597add99255f0e980d7a12ea33a3aa5585
parent3e1321ac24743cf3df1c2bb923023f9c222aa250 (diff)
parentdb6538859cd2fabb44f1f29cd87f5b498ca0c2c8 (diff)
downloadraylib-2a158c47955d2d849e939152e0c174b02c500104.tar.gz
raylib-2a158c47955d2d849e939152e0c174b02c500104.zip
Merge remote-tracking branch 'refs/remotes/raysan5/develop' into develop
-rw-r--r--.gitignore16
-rw-r--r--README.md1
-rw-r--r--docs/raylib_cheatsheet_v1.0.png (renamed from docs/cheatsheet.png)bin379936 -> 379936 bytes
-rw-r--r--docs/raylib_cheatsheet_v1.5.pngbin0 -> 2325720 bytes
-rw-r--r--examples/Makefile32
-rw-r--r--examples/audio_module_playing.c36
-rw-r--r--examples/audio_module_playing.lua122
-rw-r--r--examples/audio_music_stream.c63
-rw-r--r--examples/audio_music_stream.lua66
-rw-r--r--examples/audio_raw_stream.c111
-rw-r--r--examples/audio_raw_stream.lua97
-rw-r--r--examples/audio_sound_loading.c1
-rw-r--r--examples/audio_sound_loading.lua59
-rw-r--r--examples/audio_standalone.c11
-rw-r--r--examples/core_2d_camera.lua130
-rw-r--r--examples/core_3d_camera_first_person.c9
-rw-r--r--examples/core_3d_camera_first_person.lua85
-rw-r--r--examples/core_3d_camera_free.c9
-rw-r--r--examples/core_3d_camera_free.lua75
-rw-r--r--examples/core_3d_mode.lua64
-rw-r--r--examples/core_3d_picking.lua98
-rw-r--r--examples/core_basic_window.cpp62
-rw-r--r--examples/core_basic_window.lua44
-rw-r--r--examples/core_color_select.lua82
-rw-r--r--examples/core_drop_files.lua66
-rw-r--r--examples/core_gestures_detection.lua102
-rw-r--r--examples/core_input_gamepad.lua63
-rw-r--r--examples/core_input_keys.lua51
-rw-r--r--examples/core_input_mouse.lua54
-rw-r--r--examples/core_mouse_wheel.lua50
-rw-r--r--examples/core_oculus_rift.lua73
-rw-r--r--examples/core_random_values.lua56
-rw-r--r--examples/core_storage_values.lua74
-rw-r--r--examples/core_world_screen.lua69
-rw-r--r--examples/models_billboard.lua65
-rw-r--r--examples/models_box_collisions.lua115
-rw-r--r--examples/models_cubicmap.c10
-rw-r--r--examples/models_cubicmap.lua79
-rw-r--r--examples/models_geometric_shapes.lua67
-rw-r--r--examples/models_heightmap.lua73
-rw-r--r--examples/models_obj_loading.lua67
-rw-r--r--examples/physics_basic_rigidbody.c11
-rw-r--r--examples/physics_forces.c12
-rw-r--r--examples/resources/audio/2t2m_spa.xmbin2287400 -> 0 bytes
-rw-r--r--examples/resources/audio/chiptun1.modbin0 -> 2142 bytes
-rw-r--r--examples/resources/audio/mini1111.xmbin0 -> 25676 bytes
-rw-r--r--examples/resources/shaders/glsl100/bloom.fs30
-rw-r--r--examples/resources/shaders/glsl100/standard.fs161
-rw-r--r--examples/resources/shaders/glsl100/standard.vs23
-rw-r--r--examples/resources/shaders/glsl330/bloom.fs30
-rw-r--r--examples/resources/shaders/glsl330/standard.fs150
-rw-r--r--examples/resources/shaders/glsl330/standard.vs23
-rw-r--r--examples/rlua_execute_file.c90
-rw-r--r--examples/shaders_custom_uniform.lua115
-rw-r--r--examples/shaders_model_shader.c17
-rw-r--r--examples/shaders_model_shader.lua85
-rw-r--r--examples/shaders_postprocessing.lua101
-rw-r--r--examples/shaders_shapes_textures.lua101
-rw-r--r--examples/shaders_standard_lighting.lua114
-rw-r--r--examples/shapes_basic_shapes.lua64
-rw-r--r--examples/shapes_colors_palette.lua89
-rw-r--r--examples/shapes_logo_raylib.lua48
-rw-r--r--examples/shapes_logo_raylib_anim.lua127
-rw-r--r--examples/text_bmfont_ttf.lua59
-rw-r--r--examples/text_font_select.lua143
-rw-r--r--examples/text_format_text.lua54
-rw-r--r--examples/text_rbmf_fonts.lua87
-rw-r--r--examples/text_sprite_fonts.lua72
-rw-r--r--examples/text_writing_anim.lua52
-rw-r--r--examples/textures_formats_loading.lua217
-rw-r--r--examples/textures_image_drawing.lua70
-rw-r--r--examples/textures_image_loading.lua55
-rw-r--r--examples/textures_image_processing.lua134
-rw-r--r--examples/textures_logo_raylib.lua49
-rw-r--r--examples/textures_particles_trail_blending.lua113
-rw-r--r--examples/textures_raw_data.lua83
-rw-r--r--examples/textures_rectangle.lua69
-rw-r--r--examples/textures_srcrec_dstrec.lua71
-rw-r--r--examples/textures_to_image.lua60
-rw-r--r--games/arkanoid.lua297
-rw-r--r--games/drturtle/05_drturtle_audio.c15
-rw-r--r--games/drturtle/06_drturtle_final.c17
-rw-r--r--games/drturtle/drturtle_final_web.c19
-rw-r--r--games/just_do/just_do.c17
-rw-r--r--games/light_my_ritual/light_my_ritual.c20
-rw-r--r--games/light_my_ritual/screens/screen_gameplay.c21
-rw-r--r--games/light_my_ritual/screens/screen_logo_raylib.c5
-rw-r--r--games/makefile10
-rw-r--r--games/raylib_demo/raylib_demo.c20
-rw-r--r--games/skully_escape/skully_escape.c11
-rw-r--r--project/vs2015/examples/core_basic_window.vcxproj97
-rw-r--r--project/vs2015/examples/core_basic_window_cpp.vcxproj97
-rw-r--r--project/vs2015/external/glfw3/COPYING.txt22
-rw-r--r--project/vs2015/external/glfw3/include/GLFW/glfw3.h4235
-rw-r--r--project/vs2015/external/glfw3/include/GLFW/glfw3native.h456
-rw-r--r--project/vs2015/external/glfw3/lib/win32/glfw3.dllbin0 -> 70656 bytes
-rw-r--r--project/vs2015/external/glfw3/lib/win32/glfw3.libbin0 -> 240738 bytes
-rw-r--r--project/vs2015/external/glfw3/lib/win32/glfw3dll.libbin0 -> 24454 bytes
-rw-r--r--project/vs2015/external/lua/include/lauxlib.h256
-rw-r--r--project/vs2015/external/lua/include/lua.h486
-rw-r--r--project/vs2015/external/lua/include/lua.hpp9
-rw-r--r--project/vs2015/external/lua/include/luaconf.h769
-rw-r--r--project/vs2015/external/lua/include/lualib.h58
-rw-r--r--project/vs2015/external/lua/lib/win32/lua53.dllbin0 -> 232960 bytes
-rw-r--r--project/vs2015/external/lua/lib/win32/lua53.libbin0 -> 630434 bytes
-rw-r--r--project/vs2015/external/lua/lib/win32/lua53dll.libbin0 -> 29652 bytes
-rw-r--r--project/vs2015/external/openal_soft/COPYING484
-rw-r--r--project/vs2015/external/openal_soft/include/AL/al.h656
-rw-r--r--project/vs2015/external/openal_soft/include/AL/alc.h237
-rw-r--r--project/vs2015/external/openal_soft/include/AL/alext.h438
-rw-r--r--project/vs2015/external/openal_soft/include/AL/efx-creative.h3
-rw-r--r--project/vs2015/external/openal_soft/include/AL/efx-presets.h402
-rw-r--r--project/vs2015/external/openal_soft/include/AL/efx.h761
-rw-r--r--project/vs2015/external/openal_soft/lib/win32/OpenAL32.dllbin0 -> 845045 bytes
-rw-r--r--project/vs2015/external/openal_soft/lib/win32/OpenAL32.libbin0 -> 116274 bytes
-rw-r--r--project/vs2015/external/openal_soft/lib/win64/OpenAL32.dllbin0 -> 980543 bytes
-rw-r--r--project/vs2015/external/openal_soft/lib/win64/OpenAL32.libbin0 -> 116896 bytes
-rw-r--r--project/vs2015/raylib.sln40
-rw-r--r--project/vs2015/raylib/ReadMe.txt29
-rw-r--r--project/vs2015/raylib/raylib.vcxproj115
-rw-r--r--release/android/raylib.h10
-rw-r--r--release/html5/libraylib.bcbin721928 -> 723804 bytes
-rw-r--r--release/html5/raylib.h10
-rw-r--r--release/linux/raylib.h10
-rw-r--r--release/osx/helpme!0
-rw-r--r--release/osx/libraylib.abin0 -> 559760 bytes
-rw-r--r--release/osx/raylib.h915
-rw-r--r--release/rpi/libraylib.abin0 -> 433560 bytes
-rw-r--r--release/rpi/raylib.h915
-rw-r--r--release/win32/mingw32/libraylib.abin589058 -> 614414 bytes
-rw-r--r--release/win32/raylib.h10
-rw-r--r--shaders/glsl100/bloom.fs30
-rw-r--r--shaders/glsl100/blur.fs7
-rw-r--r--shaders/glsl100/cross_hatching.fs2
-rw-r--r--shaders/glsl100/cross_stitching.fs7
-rw-r--r--shaders/glsl100/dream_vision.fs2
-rw-r--r--shaders/glsl100/fisheye.fs2
-rw-r--r--shaders/glsl100/pixel.fs7
-rw-r--r--shaders/glsl100/posterization.fs2
-rw-r--r--shaders/glsl100/predator.fs2
-rw-r--r--shaders/glsl100/scanlines.fs2
-rw-r--r--shaders/glsl100/standard.fs13
-rw-r--r--shaders/glsl100/swirl.fs7
-rw-r--r--shaders/glsl330/bloom.fs30
-rw-r--r--shaders/glsl330/blur.fs7
-rw-r--r--shaders/glsl330/cross_hatching.fs2
-rw-r--r--shaders/glsl330/cross_stitching.fs7
-rw-r--r--shaders/glsl330/depth.fs2
-rw-r--r--shaders/glsl330/dream_vision.fs2
-rw-r--r--shaders/glsl330/fisheye.fs2
-rw-r--r--shaders/glsl330/phong.fs85
-rw-r--r--shaders/glsl330/phong.vs29
-rw-r--r--shaders/glsl330/pixel.fs7
-rw-r--r--shaders/glsl330/posterization.fs2
-rw-r--r--shaders/glsl330/predator.fs2
-rw-r--r--shaders/glsl330/scanlines.fs7
-rw-r--r--shaders/glsl330/standard.fs13
-rw-r--r--shaders/glsl330/swirl.fs7
-rw-r--r--src/Makefile53
-rw-r--r--src/android/jni/Android.mk3
-rw-r--r--src/audio.c1340
-rw-r--r--src/audio.h68
-rw-r--r--src/camera.c523
-rw-r--r--src/camera.h484
-rw-r--r--src/core.c404
-rw-r--r--src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h4
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h254
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h4
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h3
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h3
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h9
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_Version.h2
-rw-r--r--src/external/OculusSDK/LibOVR/LibOVRRT32_1.dllbin1018320 -> 1044944 bytes
-rw-r--r--src/external/jar_mod.h6
-rw-r--r--src/external/jar_xm.h62
-rw-r--r--src/external/lua/include/lauxlib.h256
-rw-r--r--src/external/lua/include/lua.h486
-rw-r--r--src/external/lua/include/lua.hpp9
-rw-r--r--src/external/lua/include/luaconf.h769
-rw-r--r--src/external/lua/include/lualib.h58
-rw-r--r--src/external/lua/lib/liblua53.abin0 -> 322424 bytes
-rw-r--r--src/external/lua/lib/liblua53dll.abin0 -> 91416 bytes
-rw-r--r--src/external/pthread/lib/pthreadGC2.dllbin0 -> 119888 bytes
-rw-r--r--src/gestures.c423
-rw-r--r--src/gestures.h480
-rw-r--r--src/models.c551
-rw-r--r--src/raygui.h1499
-rw-r--r--src/raylib.h759
-rw-r--r--src/rlgl.c293
-rw-r--r--src/rlgl.h38
-rw-r--r--src/rlua.h4206
-rw-r--r--src/shapes.c14
-rw-r--r--src/text.c222
-rw-r--r--src/textures.c527
-rw-r--r--templates/android_project/AndroidManifest.xml5
-rw-r--r--templates/android_project/jni/Android.mk4
-rw-r--r--templates/android_project/jni/basic_game.c8
-rw-r--r--templates/android_project/jni/include/raylib.h721
-rw-r--r--templates/android_project/jni/libs/libraylib.abin1868146 -> 1858024 bytes
-rw-r--r--tools/rREM/README.txt (renamed from tools/README.txt)0
-rw-r--r--tools/rREM/rrem.exe (renamed from tools/rrem.exe)bin241678 -> 241678 bytes
201 files changed, 26426 insertions, 5569 deletions
diff --git a/.gitignore b/.gitignore
index 8b584cf1..389876f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,7 +49,7 @@ ipch/
# Ignore compiled binaries
*.o
*.exe
-!tools/rrem.exe
+!tools/rREM/rrem.exe
# Ignore files build by xcode
*.mode*v*
@@ -75,4 +75,16 @@ src/libraylib.bc
!src/external/glfw3/lib/win32/glfw3.dll
!src/external/openal_soft/lib/win32/OpenAL32.dll
!src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll
-!src/external/pthread/pthreadGC2.dll
+!src/external/pthread/lib/pthreadGC2.dll
+
+# Visual Studio project
+project/vs2015/*.db
+project/vs2015/*.opendb
+!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
+
diff --git a/README.md b/README.md
index 71052a0f..64cfcc53 100644
--- a/README.md
+++ b/README.md
@@ -249,6 +249,7 @@ contributing (in some way or another) to make raylib project better. Huge thanks
- [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 (paezao) for his help on OSX to solve High DPI display issue. Thanks Marcelo!
[raysan5]: mailto:[email protected] "Ramon Santamaria - Ray San"
diff --git a/docs/cheatsheet.png b/docs/raylib_cheatsheet_v1.0.png
index e74a9833..e74a9833 100644
--- a/docs/cheatsheet.png
+++ b/docs/raylib_cheatsheet_v1.0.png
Binary files differ
diff --git a/docs/raylib_cheatsheet_v1.5.png b/docs/raylib_cheatsheet_v1.5.png
new file mode 100644
index 00000000..db362221
--- /dev/null
+++ b/docs/raylib_cheatsheet_v1.5.png
Binary files differ
diff --git a/examples/Makefile b/examples/Makefile
index 39765f15..378f5edf 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -77,8 +77,27 @@ endif
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
+# define raylib release directory for compiled library
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ RAYLIB_PATH = ../release/win32/mingw32
+ endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ RAYLIB_PATH = ../release/linux
+ endif
+ ifeq ($(PLATFORM_OS),OSX)
+ RAYLIB_PATH = ../release/osx
+ endif
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ RAYLIB_PATH = ../release/html5
+endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ RAYLIB_PATH = ../release/rpi
+endif
+
# define any directories containing required header files
-INCLUDES = -I. -I../src -I../src/external
+INCLUDES = -I. -I../src -I../src/external -I$(RAYLIB_PATH)
ifeq ($(PLATFORM),PLATFORM_RPI)
INCLUDES += -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
@@ -97,7 +116,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
endif
# define library paths containing required libs
-LFLAGS = -L. -L../src
+LFLAGS = -L. -L../src -L$(RAYLIB_PATH)
ifeq ($(PLATFORM),PLATFORM_RPI)
LFLAGS += -L/opt/vc/lib
@@ -120,7 +139,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# libraries for Debian GNU/Linux desktop compiling
# requires the following packages:
# libglfw3-dev libopenal-dev libegl1-mesa-dev
- LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -pthread -ldl
+ LIBS = -lraylib -lglfw3 -lGL -lopenal -lm -lpthread -ldl
# on XWindow could require also below libraries, just uncomment
#LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
else
@@ -210,6 +229,7 @@ EXAMPLES = \
audio_sound_loading \
audio_music_stream \
audio_module_playing \
+ audio_raw_stream \
fix_dylib \
@@ -436,10 +456,14 @@ audio_sound_loading: audio_sound_loading.c
audio_music_stream: audio_music_stream.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
-# compile [audio] example - module playing (OGG)
+# compile [audio] example - module playing (XM)
audio_module_playing: audio_module_playing.c
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
+# compile [audio] example - raw audio streaming
+audio_raw_stream: audio_raw_stream.c
+ $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
+
# fix dylib install path name for each executable (MAC)
fix_dylib:
ifeq ($(PLATFORM_OS),OSX)
diff --git a/examples/audio_module_playing.c b/examples/audio_module_playing.c
index 6189b866..7da3579c 100644
--- a/examples/audio_module_playing.c
+++ b/examples/audio_module_playing.c
@@ -57,9 +57,12 @@ int main()
// Create a RenderTexture2D to be used for render to texture
RenderTexture2D target = LoadRenderTexture(screenWidth, screenHeight);
- PlayMusicStream(0, "resources/audio/2t2m_spa.xm"); // Play module stream
+ Music xm = LoadMusicStream("resources/audio/mini1111.xm");
+
+ PlayMusicStream(xm);
float timePlayed = 0.0f;
+ bool pause = false;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -69,7 +72,29 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
- for (int i = MAX_CIRCLES - 1; i >= 0; i--)
+ UpdateMusicStream(xm); // Update music buffer with new stream data
+
+ // Restart music playing (stop and play)
+ if (IsKeyPressed(KEY_SPACE))
+ {
+ StopMusicStream(xm);
+ PlayMusicStream(xm);
+ }
+
+ // Pause/Resume music playing
+ if (IsKeyPressed(KEY_P))
+ {
+ pause = !pause;
+
+ if (pause) PauseMusicStream(xm);
+ else ResumeMusicStream(xm);
+ }
+
+ // Get timePlayed scaled to bar dimensions
+ timePlayed = (GetMusicTimePlayed(xm)/GetMusicTimeLength(xm)*(screenWidth - 40))*2;
+
+ // Color circles animation
+ for (int i = MAX_CIRCLES - 1; (i >= 0) && !pause; i--)
{
circles[i].alpha += circles[i].speed;
circles[i].radius += circles[i].speed*10.0f;
@@ -86,11 +111,6 @@ int main()
circles[i].speed = (float)GetRandomValue(1, 100)/20000.0f;
}
}
-
- // Get timePlayed scaled to bar dimensions
- timePlayed = (GetMusicTimePlayed(0)/GetMusicTimeLength(0)*(screenWidth - 40))*2;
-
- UpdateMusicStream(0); // Update music buffer with new stream data
//----------------------------------------------------------------------------------
// Draw
@@ -129,6 +149,8 @@ int main()
UnloadShader(shader); // Unload shader
UnloadRenderTexture(target); // Unload render texture
+ UnloadMusicStream(xm); // Unload music stream buffers from RAM
+
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
CloseWindow(); // Close window and OpenGL context
diff --git a/examples/audio_module_playing.lua b/examples/audio_module_playing.lua
new file mode 100644
index 00000000..3c5ad641
--- /dev/null
+++ b/examples/audio_module_playing.lua
@@ -0,0 +1,122 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [audio] example - Module playing (streaming)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+MAX_CIRCLES = 64
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [audio] example - module playing (streaming)")
+
+InitAudioDevice() -- Initialize audio device
+
+local colors = { ORANGE, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK,
+ YELLOW, GREEN, SKYBLUE, PURPLE, BEIGE }
+
+-- Creates ome circles for visual effect
+local circles = {}
+
+for i = MAX_CIRCLES, 1, -1 do
+ circles[i] = {}
+ circles[i].alpha = 0.0
+ circles[i].radius = GetRandomValue(10, 40)
+ circles[i].position = Vector2(0, 0)
+ circles[i].position.x = GetRandomValue(circles[i].radius, screenWidth - circles[i].radius)
+ circles[i].position.y = GetRandomValue(circles[i].radius, screenHeight - circles[i].radius)
+ circles[i].speed = GetRandomValue(1, 100)/20000.0
+ circles[i].color = colors[GetRandomValue(1, 14)]
+end
+
+-- Load postprocessing bloom shader
+local shader = LoadShader("resources/shaders/glsl330/base.vs",
+ "resources/shaders/glsl330/bloom.fs")
+
+-- Create a RenderTexture2D to be used for render to texture
+local target = LoadRenderTexture(screenWidth, screenHeight)
+
+local xm = LoadMusicStream("resources/audio/mini1111.xm")
+
+PlayMusicStream(xm)
+
+local timePlayed = 0.0
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ for i = MAX_CIRCLES, 1, -1 do
+ circles[i].alpha = circles[i].alpha + circles[i].speed
+ circles[i].radius = circles[i].radius + circles[i].speed*10.0
+
+ if (circles[i].alpha > 1.0) then circles[i].speed = circles[i].speed*-1 end
+
+ if (circles[i].alpha <= 0.0) then
+ circles[i].alpha = 0.0
+ circles[i].radius = GetRandomValue(10, 40)
+ circles[i].position.x = GetRandomValue(circles[i].radius, screenWidth - circles[i].radius)
+ circles[i].position.y = GetRandomValue(circles[i].radius, screenHeight - circles[i].radius)
+ circles[i].color = colors[GetRandomValue(1, 14)]
+ circles[i].speed = GetRandomValue(1, 100)/20000.0
+ end
+ end
+
+ -- Get timePlayed scaled to bar dimensions
+ timePlayed = (GetMusicTimePlayed(xm)/GetMusicTimeLength(xm)*(screenWidth - 40))*2
+
+ UpdateMusicStream(xm) -- Update music buffer with new stream data
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(BLACK)
+
+ BeginTextureMode(target) -- Enable drawing to texture
+
+ for i = MAX_CIRCLES, 1, -1 do
+ DrawCircleV(circles[i].position, circles[i].radius, Fade(circles[i].color, circles[i].alpha))
+ end
+
+ EndTextureMode() -- End drawing to texture (now we have a texture available for next passes)
+
+ BeginShaderMode(shader)
+
+ -- NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
+ DrawTextureRec(target.texture, Rectangle(0, 0, target.texture.width, -target.texture.height), Vector2(0, 0), WHITE)
+
+ EndShaderMode()
+
+ -- Draw time bar
+ DrawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, LIGHTGRAY)
+ DrawRectangle(20, screenHeight - 20 - 12, timePlayed//1, 12, MAROON)
+ DrawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, WHITE)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadShader(shader) -- Unload shader
+UnloadRenderTexture(target) -- Unload render texture
+
+UnloadMusicStream(xm) -- Unload music stream buffers from RAM
+
+CloseAudioDevice() -- Close audio device (music streaming is automatically stopped)
+
+CloseWindow() -- Close window and OpenGL context
+-------------------------------------------------------------------------------------------
diff --git a/examples/audio_music_stream.c b/examples/audio_music_stream.c
index e135a6e4..dc9d4355 100644
--- a/examples/audio_music_stream.c
+++ b/examples/audio_music_stream.c
@@ -24,11 +24,12 @@ int main()
InitAudioDevice(); // Initialize audio device
- PlayMusicStream(0, "resources/audio/guitar_noodling.ogg"); // Play music stream
+ Music music = LoadMusicStream("resources/audio/guitar_noodling.ogg");
+
+ PlayMusicStream(music);
- int framesCounter = 0;
float timePlayed = 0.0f;
- //float volume = 1.0;
+ bool pause = false;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -38,32 +39,26 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
- framesCounter++;
-
- // Testing music fading from one file to another
-/*
- if (framesCounter > 600) // Wait for 10 seconds (600 frames)
+ UpdateMusicStream(music); // Update music buffer with new stream data
+
+ // Restart music playing (stop and play)
+ if (IsKeyPressed(KEY_SPACE))
{
- volume -= 0.01; // Decrement music volume level
-
- // When music volume level equal or lower than 0,
- // restore volume level and init another music file
- if (volume <= 0)
- {
- volume = 1.0;
- framesCounter = 0;
- PlayMusicStream(1, "resources/audio/another_file.ogg");
- }
-
- SetMusicVolume(volume);
+ StopMusicStream(music);
+ PlayMusicStream(music);
}
-*/
- if (IsWindowMinimized()) PauseMusicStream(0);
- else ResumeMusicStream(0);
-
- timePlayed = GetMusicTimePlayed(0)/GetMusicTimeLength(0)*100*4; // We scale by 4 to fit 400 pixels
- UpdateMusicStream(0); // Update music buffer with new stream data
+ // Pause/Resume music playing
+ if (IsKeyPressed(KEY_P))
+ {
+ pause = !pause;
+
+ if (pause) PauseMusicStream(music);
+ else ResumeMusicStream(music);
+ }
+
+ // Get timePlayed scaled to bar dimensions (400 pixels)
+ timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4;
//----------------------------------------------------------------------------------
// Draw
@@ -72,10 +67,14 @@ int main()
ClearBackground(RAYWHITE);
- DrawText("MUSIC SHOULD BE PLAYING!", 255, 200, 20, LIGHTGRAY);
+ DrawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, LIGHTGRAY);
- DrawRectangle(200, 250, 400, 12, LIGHTGRAY);
- DrawRectangle(200, 250, (int)timePlayed, 12, MAROON);
+ DrawRectangle(200, 200, 400, 12, LIGHTGRAY);
+ DrawRectangle(200, 200, (int)timePlayed, 12, MAROON);
+ DrawRectangleLines(200, 200, 400, 12, GRAY);
+
+ DrawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, LIGHTGRAY);
+ DrawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
@@ -83,9 +82,11 @@ int main()
// De-Initialization
//--------------------------------------------------------------------------------------
- CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
+ UnloadMusicStream(music); // Unload music stream buffers from RAM
+
+ CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
- CloseWindow(); // Close window and OpenGL context
+ CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
diff --git a/examples/audio_music_stream.lua b/examples/audio_music_stream.lua
new file mode 100644
index 00000000..33cf335f
--- /dev/null
+++ b/examples/audio_music_stream.lua
@@ -0,0 +1,66 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [audio] example - Music playing (streaming)
+--
+-- NOTE: This example requires OpenAL Soft library installed
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [audio] example - music playing (streaming)")
+
+InitAudioDevice() -- Initialize audio device
+
+local music = LoadMusicStream("resources/audio/guitar_noodling.ogg")
+
+PlayMusicStream(music)
+
+local framesCounter = 0
+local timePlayed = 0.0
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ framesCounter = framesCounter + 1
+
+ timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4 -- We scale by 4 to fit 400 pixels
+
+ UpdateMusicStream(music) -- Update music buffer with new stream data
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("MUSIC SHOULD BE PLAYING!", 255, 200, 20, LIGHTGRAY)
+
+ DrawRectangle(200, 250, 400, 12, LIGHTGRAY)
+ DrawRectangle(200, 250, timePlayed//1, 12, MAROON)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadMusicStream(music) -- Unload music stream buffers from RAM
+
+CloseAudioDevice() -- Close audio device (music streaming is automatically stopped)
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/audio_raw_stream.c b/examples/audio_raw_stream.c
new file mode 100644
index 00000000..c044a7e0
--- /dev/null
+++ b/examples/audio_raw_stream.c
@@ -0,0 +1,111 @@
+/*******************************************************************************************
+*
+* raylib [audio] example - Raw audio streaming
+*
+* NOTE: This example requires OpenAL Soft library installed
+*
+* This example has been created using raylib 1.6 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2015 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#include <stdlib.h> // Required for: malloc(), free()
+#include <math.h> // Required for: sinf()
+
+#define MAX_SAMPLES 20000
+
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 800;
+ int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw audio streaming");
+
+ InitAudioDevice(); // Initialize audio device
+
+ // Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono)
+ AudioStream stream = InitAudioStream(22050, 32, 1);
+
+ // Fill audio stream with some samples (sine wave)
+ float *data = (float *)malloc(sizeof(float)*MAX_SAMPLES);
+
+ for (int i = 0; i < MAX_SAMPLES; i++)
+ {
+ data[i] = sinf(((2*PI*(float)i)/2)*DEG2RAD);
+ }
+
+ // NOTE: The generated MAX_SAMPLES do not fit to close a perfect loop
+ // for that reason, there is a clip everytime audio stream is looped
+
+ PlayAudioStream(stream);
+
+ int totalSamples = MAX_SAMPLES;
+ int samplesLeft = totalSamples;
+
+ Vector2 position = { 0, 0 };
+
+ SetTargetFPS(30); // Set our game to run at 30 frames-per-second
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+
+ // Refill audio stream if required
+ if (IsAudioBufferProcessed(stream))
+ {
+ int numSamples = 0;
+ if (samplesLeft >= 4096) numSamples = 4096;
+ else numSamples = samplesLeft;
+
+ UpdateAudioStream(stream, data + (totalSamples - samplesLeft), numSamples);
+
+ samplesLeft -= numSamples;
+
+ // Reset samples feeding (loop audio)
+ if (samplesLeft <= 0) samplesLeft = totalSamples;
+ }
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ DrawText("SINE WAVE SHOULD BE PLAYING!", 240, 140, 20, LIGHTGRAY);
+
+ // NOTE: Draw a part of the sine wave (only screen width)
+ for (int i = 0; i < GetScreenWidth(); i++)
+ {
+ position.x = i;
+ position.y = 250 + 50*data[i];
+
+ DrawPixelV(position, RED);
+ }
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ free(data); // Unload sine wave data
+
+ CloseAudioStream(stream); // Close raw audio stream and delete buffers from RAM
+
+ CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
+
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/examples/audio_raw_stream.lua b/examples/audio_raw_stream.lua
new file mode 100644
index 00000000..070984f9
--- /dev/null
+++ b/examples/audio_raw_stream.lua
@@ -0,0 +1,97 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [audio] example - Raw audio streaming
+--
+-- NOTE: This example requires OpenAL Soft library installed
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+MAX_SAMPLES = 20000
+DEG2RAD = math.pi/180.0
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [audio] example - raw audio streaming")
+
+InitAudioDevice() -- Initialize audio device
+
+-- Init raw audio stream (sample rate: 22050, sample size: 32bit-float, channels: 1-mono)
+local stream = InitAudioStream(22050, 32, 1)
+
+-- Fill audio stream with some samples (sine wave)
+local data = {}
+
+for i = 1, MAX_SAMPLES do
+ data[i] = math.sin(((2*math.pi*i)/2)*DEG2RAD)
+end
+
+-- NOTE: The generated MAX_SAMPLES do not fit to close a perfect loop
+-- for that reason, there is a clip everytime audio stream is looped
+
+PlayAudioStream(stream)
+
+local totalSamples = MAX_SAMPLES
+local samplesLeft = totalSamples
+
+local position = Vector2(0, 0)
+
+SetTargetFPS(30) -- Set our game to run at 30 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+
+ -- Refill audio stream if required
+ if (IsAudioBufferProcessed(stream)) then
+ local numSamples = 0
+
+ if (samplesLeft >= 4096) then numSamples = 4096
+ else numSamples = samplesLeft end
+
+ UpdateAudioStream(stream, data + (totalSamples - samplesLeft), numSamples)
+
+ samplesLeft = samplesLeft - numSamples
+
+ -- Reset samples feeding (loop audio)
+ if (samplesLeft <= 0) then samplesLeft = totalSamples end
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("SINE WAVE SHOULD BE PLAYING!", 240, 140, 20, LIGHTGRAY)
+
+ -- NOTE: Draw a part of the sine wave (only screen width)
+ for i = 1, GetScreenWidth() do
+ position.x = (i - 1)
+ position.y = 250 + 50*data[i]
+
+ DrawPixelV(position, RED)
+ end
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseAudioStream(stream) -- Close raw audio stream and delete buffers from RAM
+
+CloseAudioDevice() -- Close audio device (music streaming is automatically stopped)
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/audio_sound_loading.c b/examples/audio_sound_loading.c
index 8819aad1..f081e8ed 100644
--- a/examples/audio_sound_loading.c
+++ b/examples/audio_sound_loading.c
@@ -36,7 +36,6 @@ int main()
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_SPACE)) PlaySound(fxWav); // Play WAV sound
-
if (IsKeyPressed(KEY_ENTER)) PlaySound(fxOgg); // Play OGG sound
//----------------------------------------------------------------------------------
diff --git a/examples/audio_sound_loading.lua b/examples/audio_sound_loading.lua
new file mode 100644
index 00000000..7107eea4
--- /dev/null
+++ b/examples/audio_sound_loading.lua
@@ -0,0 +1,59 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [audio] example - Sound loading and playing
+--
+-- NOTE: This example requires OpenAL Soft library installed
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [audio] example - sound loading and playing")
+
+InitAudioDevice() -- Initialize audio device
+
+local fxWav = LoadSound("resources/audio/weird.wav") -- Load WAV audio file
+local fxOgg = LoadSound("resources/audio/tanatana.ogg") -- Load OGG audio file
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsKeyPressed(KEY.SPACE)) then PlaySound(fxWav) end -- Play WAV sound
+ if (IsKeyPressed(KEY.ENTER)) then PlaySound(fxOgg) end -- Play OGG sound
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, LIGHTGRAY)
+
+ DrawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, LIGHTGRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadSound(fxWav) -- Unload sound data
+UnloadSound(fxOgg) -- Unload sound data
+
+CloseAudioDevice() -- Close audio device
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/audio_standalone.c b/examples/audio_standalone.c
index f6e115db..c716faed 100644
--- a/examples/audio_standalone.c
+++ b/examples/audio_standalone.c
@@ -39,7 +39,8 @@ int main()
Sound fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file
Sound fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file
- PlayMusicStream(0, "resources/audio/guitar_noodling.ogg");
+ Music music = LoadMusicStream("resources/audio/guitar_noodling.ogg");
+ PlayMusicStream(music);
printf("\nPress s or d to play sounds...\n");
@@ -59,11 +60,13 @@ int main()
key = 0;
}
- UpdateMusicStream(0);
+ UpdateMusicStream(music);
}
- UnloadSound(fxWav); // Unload sound data
- UnloadSound(fxOgg); // Unload sound data
+ UnloadSound(fxWav); // Unload sound data
+ UnloadSound(fxOgg); // Unload sound data
+
+ UnloadMusicStream(music); // Unload music stream data
CloseAudioDevice();
diff --git a/examples/core_2d_camera.lua b/examples/core_2d_camera.lua
new file mode 100644
index 00000000..95302c26
--- /dev/null
+++ b/examples/core_2d_camera.lua
@@ -0,0 +1,130 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - 2d camera
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+MAX_BUILDINGS = 100
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - 2d camera")
+
+local player = Rectangle(400, 280, 40, 40)
+local buildings = {}
+local buildColors = {}
+
+local spacing = 0;
+
+for i = 1, MAX_BUILDINGS do
+ buildings[i] = Rectangle(0, 0, 0, 0)
+ buildings[i].width = GetRandomValue(50, 200)
+ buildings[i].height = GetRandomValue(100, 800)
+ buildings[i].y = screenHeight - 130 - buildings[i].height
+ buildings[i].x = -6000 + spacing
+
+ spacing = spacing + buildings[i].width
+
+ buildColors[i] = Color(GetRandomValue(200, 240), GetRandomValue(200, 240), GetRandomValue(200, 250), 255)
+end
+
+local camera = Camera2D(Vector2(0, 0), Vector2(0, 0), 0.0, 1.0)
+
+camera.target = Vector2(player.x + 20, player.y + 20)
+camera.offset = Vector2(0, 0)
+camera.rotation = 0.0
+camera.zoom = 1.0
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsKeyDown(KEY.RIGHT)) then
+ player.x = player.x + 2 -- Player movement
+ camera.offset.x = camera.offset.x - 2 -- Camera displacement with player movement
+ elseif (IsKeyDown(KEY.LEFT)) then
+ player.x = player.x - 2 -- Player movement
+ camera.offset.x = camera.offset.x + 2 -- Camera displacement with player movement
+ end
+
+ -- Camera target follows player
+ camera.target = Vector2(player.x + 20, player.y + 20)
+
+ -- Camera rotation controls
+ if (IsKeyDown(KEY.A)) then camera.rotation = camera.rotation - 1
+ elseif (IsKeyDown(KEY.S)) then camera.rotation = camera.rotation + 1
+ end
+
+ -- Limit camera rotation to 80 degrees (-40 to 40)
+ if (camera.rotation > 40) then camera.rotation = 40
+ elseif (camera.rotation < -40) then camera.rotation = -40
+ end
+
+ -- Camera zoom controls
+ camera.zoom = camera.zoom + (GetMouseWheelMove()*0.05)
+
+ if (camera.zoom > 3.0) then camera.zoom = 3.0
+ elseif (camera.zoom < 0.1) then camera.zoom = 0.1
+ end
+
+ -- Camera reset (zoom and rotation)
+ if (IsKeyPressed(KEY.R)) then
+ camera.zoom = 1.0
+ camera.rotation = 0.0
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin2dMode(camera)
+
+ DrawRectangle(-6000, 320, 13000, 8000, DARKGRAY)
+
+ for i = 1, MAX_BUILDINGS, 1 do DrawRectangleRec(buildings[i], buildColors[i]) end
+
+ DrawRectangleRec(player, RED)
+
+ DrawRectangle(camera.target.x, -500, 1, screenHeight*4, GREEN)
+ DrawRectangle(-500, camera.target.y, screenWidth*4, 1, GREEN)
+
+ End2dMode()
+
+ DrawText("SCREEN AREA", 640, 10, 20, RED)
+
+ DrawRectangle(0, 0, screenWidth, 5, RED)
+ DrawRectangle(0, 5, 5, screenHeight - 10, RED)
+ DrawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, RED)
+ DrawRectangle(0, screenHeight - 5, screenWidth, 5, RED)
+
+ DrawRectangle( 10, 10, 250, 113, Fade(SKYBLUE, 0.5))
+ DrawRectangleLines( 10, 10, 250, 113, BLUE)
+
+ DrawText("Free 2d camera controls:", 20, 20, 10, BLACK)
+ DrawText("- Right/Left to move Offset", 40, 40, 10, DARKGRAY)
+ DrawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, DARKGRAY)
+ DrawText("- A / S to Rotate", 40, 80, 10, DARKGRAY)
+ DrawText("- R to reset Zoom and Rotation", 40, 100, 10, DARKGRAY)
+
+ EndDrawing();
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+-------------------------------------------------------------------------------------------
diff --git a/examples/core_3d_camera_first_person.c b/examples/core_3d_camera_first_person.c
index 56e38a23..27ff5135 100644
--- a/examples/core_3d_camera_first_person.c
+++ b/examples/core_3d_camera_first_person.c
@@ -23,7 +23,7 @@ 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 = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f };
+ Camera camera = {{ 4.0f, 2.0f, 4.0f }, { 0.0f, 1.8f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f };
// Generates some random columns
float heights[MAX_COLUMNS];
@@ -37,10 +37,7 @@ int main()
colors[i] = (Color){ GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255 };
}
- Vector3 playerPosition = { 4.0f, 2.0f, 4.0f }; // Define player position
-
- SetCameraMode(CAMERA_FIRST_PERSON); // Set a first person camera mode
- SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
+ SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set a first person camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -50,7 +47,7 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
- UpdateCameraPlayer(&camera, &playerPosition); // Update camera and player position
+ UpdateCamera(&camera); // Update camera and player position
//----------------------------------------------------------------------------------
// Draw
diff --git a/examples/core_3d_camera_first_person.lua b/examples/core_3d_camera_first_person.lua
new file mode 100644
index 00000000..800c3c2a
--- /dev/null
+++ b/examples/core_3d_camera_first_person.lua
@@ -0,0 +1,85 @@
+--------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - 3d camera first person
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+--------------------------------------------------------------------------------------------
+
+MAX_COLUMNS = 20
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person")
+
+-- Define the camera to look into our 3d world (position, target, up vector)
+local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 60.0)
+
+-- Generates some random columns
+local heights = {}
+local positions = {}
+local colors = {}
+
+for i = 1, MAX_COLUMNS do
+ heights[i] = GetRandomValue(1, 12)
+ positions[i] = Vector3(GetRandomValue(-15, 15), heights[i]/2, GetRandomValue(-15, 15))
+ colors[i] = Color(GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255)
+end
+
+local playerPosition = Vector3(4.0, 2.0, 4.0) -- Define player position
+
+SetCameraMode(CameraMode.FIRST_PERSON) -- Set a first person camera mode
+SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera, playerPosition = UpdateCameraPlayer(camera, playerPosition) -- Update camera and player position
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawPlane(Vector3(0.0, 0.0, 0.0), Vector2(32.0, 32.0), LIGHTGRAY) -- Draw ground
+ DrawCube(Vector3(-16.0, 2.5, 0.0), 1.0, 5.0, 32.0, BLUE) -- Draw a blue wall
+ DrawCube(Vector3(16.0, 2.5, 0.0), 1.0, 5.0, 32.0, LIME) -- Draw a green wall
+ DrawCube(Vector3(0.0, 2.5, 16.0), 32.0, 5.0, 1.0, GOLD) -- Draw a yellow wall
+
+ -- Draw some cubes around
+ for i = 1, MAX_COLUMNS do
+ DrawCube(positions[i], 2.0, heights[i], 2.0, colors[i])
+ DrawCubeWires(positions[i], 2.0, heights[i], 2.0, MAROON)
+ end
+
+ End3dMode()
+
+ DrawRectangle( 10, 10, 220, 70, Fade(SKYBLUE, 0.5))
+ DrawRectangleLines( 10, 10, 220, 70, BLUE)
+
+ DrawText("First person camera default controls:", 20, 20, 10, BLACK)
+ DrawText("- Move with keys: W, A, S, D", 40, 40, 10, DARKGRAY)
+ DrawText("- Mouse move to look around", 40, 60, 10, DARKGRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_3d_camera_free.c b/examples/core_3d_camera_free.c
index fa7ad85f..c798f225 100644
--- a/examples/core_3d_camera_free.c
+++ b/examples/core_3d_camera_free.c
@@ -22,17 +22,14 @@ int main()
// Define the camera to look into our 3d world
Camera camera;
- camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position
+ camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position
camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target)
camera.fovy = 45.0f; // Camera field-of-view Y
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
- SetCameraMode(CAMERA_FREE); // Set a free camera mode
- SetCameraPosition(camera.position); // Set internal camera position to match our camera position
- SetCameraTarget(camera.target); // Set internal camera target to match our camera target
- SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
+ SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
@@ -43,6 +40,8 @@ int main()
// Update
//----------------------------------------------------------------------------------
UpdateCamera(&camera); // Update internal camera and our camera
+
+ if (IsKeyDown('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
//----------------------------------------------------------------------------------
// Draw
diff --git a/examples/core_3d_camera_free.lua b/examples/core_3d_camera_free.lua
new file mode 100644
index 00000000..244aad6b
--- /dev/null
+++ b/examples/core_3d_camera_free.lua
@@ -0,0 +1,75 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Initialize 3d camera free
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+--------------------------------------------------------------------------------------------
+
+-- Initialization
+----------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free")
+
+-- Define the camera to look into our 3d world
+local camera = {}
+camera.position = Vector3(0.0, 10.0, 10.0) -- Camera position
+camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point
+camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target)
+camera.fovy = 45.0 -- Camera field-of-view Y
+
+local cubePosition = Vector3(0.0, 0.0, 0.0)
+
+SetCameraMode(CameraMode.FREE) -- Set a free camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraTarget(camera.target) -- Set internal camera target to match our camera target
+SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawCube(cubePosition, 2.0, 2.0, 2.0, RED)
+ DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON)
+
+ DrawGrid(10, 1.0)
+
+ End3dMode()
+
+ DrawRectangle( 10, 10, 320, 133, Fade(SKYBLUE, 0.5))
+ DrawRectangleLines( 10, 10, 320, 133, BLUE)
+
+ DrawText("Free camera default controls:", 20, 20, 10, BLACK)
+ DrawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, DARKGRAY)
+ DrawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, DARKGRAY)
+ DrawText("- Alt + Mouse Wheel Pressed to Rotate", 40, 80, 10, DARKGRAY)
+ DrawText("- Alt + Ctrl + Mouse Wheel Pressed for Smooth Zoom", 40, 100, 10, DARKGRAY)
+ DrawText("- Z to zoom to (0, 0, 0)", 40, 120, 10, DARKGRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_3d_mode.lua b/examples/core_3d_mode.lua
new file mode 100644
index 00000000..c0f7a038
--- /dev/null
+++ b/examples/core_3d_mode.lua
@@ -0,0 +1,64 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Initialize 3d mode
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d mode")
+
+-- Define the camera to look into our 3d world
+local camera = {}
+camera.position = Vector3(0.0, 10.0, 10.0) -- Camera position
+camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point
+camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target)
+camera.fovy = 45.0 -- Camera field-of-view Y
+
+local cubePosition = Vector3(0.0, 0.0, 0.0)
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera) -- ERROR: Lua Error: attempt to index a number value (?)
+
+ DrawCube(cubePosition, 2.0, 2.0, 2.0, RED)
+ DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON)
+
+ DrawGrid(10, 1.0)
+
+ End3dMode()
+
+ DrawText("Welcome to the third dimension!", 10, 40, 20, DARKGRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_3d_picking.lua b/examples/core_3d_picking.lua
new file mode 100644
index 00000000..1adee67c
--- /dev/null
+++ b/examples/core_3d_picking.lua
@@ -0,0 +1,98 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Picking in 3d mode
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d picking")
+
+-- Define the camera to look into our 3d world
+local camera = {}
+camera.position = Vector3(0.0, 10.0, 10.0) -- Camera position
+camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point
+camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target)
+camera.fovy = 45.0 -- Camera field-of-view Y
+
+local cubePosition = Vector3(0.0, 1.0, 0.0)
+local cubeSize = Vector3(2.0, 2.0, 2.0)
+
+local ray = Ray(Vector3(0, 0, 0), Vector3(0, 0, 0)) -- Picking line ray
+
+local collision = false
+
+SetCameraMode(CameraMode.FREE) -- Set a free camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+
+ if (IsMouseButtonPressed(MOUSE.LEFT_BUTTON)) then
+ -- NOTE: This function is NOT WORKING properly!
+ 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),
+ Vector3(cubePosition.x + cubeSize.x/2, cubePosition.y + cubeSize.y/2, cubePosition.z + cubeSize.z/2)))
+
+ --print("collision check:", collision)
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ if (collision) then
+ DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, RED)
+ DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, MAROON)
+
+ DrawCubeWires(cubePosition, cubeSize.x + 0.2, cubeSize.y + 0.2, cubeSize.z + 0.2, GREEN)
+ else
+ DrawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, GRAY)
+ DrawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, DARKGRAY)
+ end
+
+ DrawRay(ray, MAROON)
+
+ DrawGrid(10, 1.0)
+
+ End3dMode()
+
+ DrawText("Try selecting the box with mouse!", 240, 10, 20, DARKGRAY)
+
+ if (collision) then
+ DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30))/2, screenHeight*0.1, 30, GREEN)
+ end
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_basic_window.cpp b/examples/core_basic_window.cpp
new file mode 100644
index 00000000..fa12026a
--- /dev/null
+++ b/examples/core_basic_window.cpp
@@ -0,0 +1,62 @@
+/*******************************************************************************************
+*
+* raylib [core] example - Basic window
+*
+* Welcome to raylib!
+*
+* To test examples, just press F6 and execute raylib_compile_execute script
+* Note that compiled executable is placed in the same folder as .c file
+*
+* You can find all basic examples on C:\raylib\raylib\examples folder or
+* raylib official webpage: www.raylib.com
+*
+* Enjoy using raylib. :)
+*
+* This example has been created using raylib 1.0 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2014 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+int main(int argc, char* argv[])
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ int screenWidth = 800;
+ int screenHeight = 450;
+
+ InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
+
+ SetTargetFPS(60);
+ //--------------------------------------------------------------------------------------
+
+ // Main game loop
+ while (!WindowShouldClose()) // Detect window close button or ESC key
+ {
+ // Update
+ //----------------------------------------------------------------------------------
+ // TODO: Update your variables here
+ //----------------------------------------------------------------------------------
+
+ // Draw
+ //----------------------------------------------------------------------------------
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY);
+
+ EndDrawing();
+ //----------------------------------------------------------------------------------
+ }
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseWindow(); // Close window and OpenGL context
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/examples/core_basic_window.lua b/examples/core_basic_window.lua
new file mode 100644
index 00000000..ea3337a1
--- /dev/null
+++ b/examples/core_basic_window.lua
@@ -0,0 +1,44 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Basic window
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window")
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_color_select.lua b/examples/core_color_select.lua
new file mode 100644
index 00000000..2d9c7a96
--- /dev/null
+++ b/examples/core_color_select.lua
@@ -0,0 +1,82 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Color selection by mouse (collision detection)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+NUM_RECTANGLES = 21
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - color selection (collision detection)")
+
+local colors = { DARKGRAY, MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, DARKBROWN,
+ GRAY, RED, GOLD, LIME, BLUE, VIOLET, BROWN, LIGHTGRAY, PINK, YELLOW,
+ GREEN, SKYBLUE, PURPLE, BEIGE }
+
+local colorsRecs = {} -- Rectangles array
+local selected = {}
+
+-- Fills colorsRecs data (for every rectangle)
+for i = 1, NUM_RECTANGLES do
+ colorsRecs[i] = Rectangle(0, 0, 0, 0)
+ colorsRecs[i].x = 20 + 100*((i-1)%7) + 10*((i-1)%7)
+ colorsRecs[i].y = 60 + 100*((i-1)//7) + 10*((i-1)//7) -- Using floor division: //
+ colorsRecs[i].width = 100
+ colorsRecs[i].height = 100
+ selected[i] = false
+end
+
+local mousePoint = Vector2(0, 0)
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ mousePoint = GetMousePosition()
+
+ for i = 1, NUM_RECTANGLES do -- Iterate along all the rectangles
+ if (CheckCollisionPointRec(mousePoint, colorsRecs[i])) then
+ colors[i].a = 120
+ if (IsMouseButtonPressed(MOUSE.LEFT_BUTTON)) then selected[i] = not selected[i] end
+ else colors[i].a = 255 end
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ for i = 1, NUM_RECTANGLES do -- Draw all rectangles
+ DrawRectangleRec(colorsRecs[i], colors[i])
+
+ -- Draw four rectangles around selected rectangle
+ if (selected[i]) then
+ DrawRectangle(colorsRecs[i].x, colorsRecs[i].y, 100, 10, RAYWHITE) -- Square top rectangle
+ DrawRectangle(colorsRecs[i].x, colorsRecs[i].y, 10, 100, RAYWHITE) -- Square left rectangle
+ DrawRectangle(colorsRecs[i].x + 90, colorsRecs[i].y, 10, 100, RAYWHITE) -- Square right rectangle
+ DrawRectangle(colorsRecs[i].x, colorsRecs[i].y + 90, 100, 10, RAYWHITE) -- Square bottom rectangle
+ end
+ end
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_drop_files.lua b/examples/core_drop_files.lua
new file mode 100644
index 00000000..1d27e618
--- /dev/null
+++ b/examples/core_drop_files.lua
@@ -0,0 +1,66 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Windows drop files
+--
+-- This example only works on platforms that support drag & drop (Windows, Linux, OSX)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - drop files")
+
+local count = 0
+local droppedFiles = {}
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsFileDropped()) then
+ droppedFiles = GetDroppedFiles()
+ count = #droppedFiles
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ if (count == 0) then DrawText("Drop your files to this window!", 100, 40, 20, DARKGRAY)
+ else
+ DrawText("Dropped files:", 100, 40, 20, DARKGRAY)
+
+ for i = 0, count-1 do
+ if (i%2 == 0) then DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.5))
+ else DrawRectangle(0, 85 + 40*i, screenWidth, 40, Fade(LIGHTGRAY, 0.3)) end
+
+ DrawText(droppedFiles[i+1], 120, 100 + 40*i, 10, GRAY)
+ end
+
+ DrawText("Drop new files...", 100, 110 + 40*count, 20, DARKGRAY)
+ end
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+ClearDroppedFiles() -- Clear internal buffers
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_gestures_detection.lua b/examples/core_gestures_detection.lua
new file mode 100644
index 00000000..9316b990
--- /dev/null
+++ b/examples/core_gestures_detection.lua
@@ -0,0 +1,102 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Gestures Detection
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+MAX_GESTURE_STRINGS = 20
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - gestures detection")
+
+local touchPosition = Vector2(0, 0)
+local touchArea = Rectangle(220, 10, screenWidth - 230, screenHeight - 20)
+
+local gesturesCount = 0
+local gestureStrings = {}
+
+for i = 1, MAX_GESTURE_STRINGS do gestureStrings[i] = "" end
+
+local currentGesture = Gestures.NONE
+local lastGesture = Gestures.NONE
+
+--SetGesturesEnabled(0b0000000000001001) -- Enable only some gestures to be detected
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ lastGesture = currentGesture
+ currentGesture = GetGestureDetected()
+ touchPosition = GetTouchPosition(0)
+
+ if (CheckCollisionPointRec(touchPosition, touchArea) and (currentGesture ~= Gestures.NONE)) then
+ if (currentGesture ~= lastGesture) then
+ -- Store gesture string
+ if (currentGesture == Gestures.TAP) then gestureStrings[gesturesCount] = "GESTURE TAP"
+ elseif (currentGesture == Gestures.DOUBLETAP) then gestureStrings[gesturesCount] = "GESTURE DOUBLETAP"
+ elseif (currentGesture == Gestures.HOLD) then gestureStrings[gesturesCount] = "GESTURE HOLD"
+ elseif (currentGesture == Gestures.DRAG) then gestureStrings[gesturesCount] = "GESTURE DRAG"
+ elseif (currentGesture == Gestures.SWIPE_RIGHT) then gestureStrings[gesturesCount] = "GESTURE SWIPE RIGHT"
+ elseif (currentGesture == Gestures.SWIPE_LEFT) then gestureStrings[gesturesCount] = "GESTURE SWIPE LEFT"
+ elseif (currentGesture == Gestures.SWIPE_UP) then gestureStrings[gesturesCount] = "GESTURE SWIPE UP"
+ elseif (currentGesture == Gestures.SWIPE_DOWN) then gestureStrings[gesturesCount] = "GESTURE SWIPE DOWN"
+ elseif (currentGesture == Gestures.PINCH_IN) then gestureStrings[gesturesCount] = "GESTURE PINCH IN"
+ elseif (currentGesture == Gestures.PINCH_OUT) then gestureStrings[gesturesCount] = "GESTURE PINCH OUT"
+ end
+
+ gesturesCount = gesturesCount + 1
+
+ -- Reset gestures strings
+ if (gesturesCount >= MAX_GESTURE_STRINGS) then
+ for i = 1, MAX_GESTURE_STRINGS do gestureStrings[i] = "\0" end
+ gesturesCount = 0
+ end
+ end
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawRectangleRec(touchArea, GRAY)
+ DrawRectangle(225, 15, screenWidth - 240, screenHeight - 30, RAYWHITE)
+
+ DrawText("GESTURES TEST AREA", screenWidth - 270, screenHeight - 40, 20, Fade(GRAY, 0.5))
+
+ for i = 1, gesturesCount do
+ if ((i - 1)%2 == 0) then DrawRectangle(10, 30 + 20*(i - 1), 200, 20, Fade(LIGHTGRAY, 0.5))
+ else DrawRectangle(10, 30 + 20*(i - 1), 200, 20, Fade(LIGHTGRAY, 0.3)) end
+
+ if (i < gesturesCount) then DrawText(gestureStrings[i], 35, 36 + 20*(i - 1), 10, DARKGRAY)
+ else DrawText(gestureStrings[i], 35, 36 + 20*(i - 1), 10, MAROON) end
+ end
+
+ DrawRectangleLines(10, 29, 200, screenHeight - 50, GRAY)
+ DrawText("DETECTED GESTURES", 50, 15, 10, GRAY)
+
+ if (currentGesture ~= GESTURE_NONE) then DrawCircleV(touchPosition, 30, MAROON) end
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_input_gamepad.lua b/examples/core_input_gamepad.lua
new file mode 100644
index 00000000..78d9b84e
--- /dev/null
+++ b/examples/core_input_gamepad.lua
@@ -0,0 +1,63 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Gamepad input
+--
+-- NOTE: This example requires a Gamepad connected to the system
+-- raylib is configured to work with Xbox 360 gamepad, check raylib.h for buttons configuration
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - gamepad input")
+
+local ballPosition = Vector2(screenWidth/2, screenHeight/2)
+local gamepadMovement = Vector2(0, 0)
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsGamepadAvailable(GAMEPAD.PLAYER1)) then
+ gamepadMovement.x = GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_X)
+ gamepadMovement.y = GetGamepadAxisMovement(GAMEPAD.PLAYER1, GAMEPAD.XBOX_AXIS_LEFT_Y)
+
+ ballPosition.x = ballPosition.x + gamepadMovement.x
+ ballPosition.y = ballPosition.y - gamepadMovement.y
+
+ if (IsGamepadButtonPressed(GAMEPAD.PLAYER1, GAMEPAD.BUTTON_A)) then
+ ballPosition.x = screenWidth/2
+ ballPosition.y = screenHeight/2
+ end
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("move the ball with gamepad", 10, 10, 20, DARKGRAY)
+
+ DrawCircleV(ballPosition, 50, MAROON)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_input_keys.lua b/examples/core_input_keys.lua
new file mode 100644
index 00000000..523b7317
--- /dev/null
+++ b/examples/core_input_keys.lua
@@ -0,0 +1,51 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Keyboard input
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window")
+
+local ballPosition = Vector2(screenWidth/2, screenHeight/2)
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsKeyDown(KEY.RIGHT)) then ballPosition.x = ballPosition.x + 0.8 end
+ if (IsKeyDown(KEY.LEFT)) then ballPosition.x = ballPosition.x - 0.8 end
+ if (IsKeyDown(KEY.UP)) then ballPosition.y = ballPosition.y - 0.8 end
+ if (IsKeyDown(KEY.DOWN)) then ballPosition.y = ballPosition.y + 0.8 end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("move the ball with arrow keys", 10, 10, 20, DARKGRAY)
+
+ DrawCircleV(ballPosition, 50, MAROON)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+-------------------------------------------------------------------------------------------
diff --git a/examples/core_input_mouse.lua b/examples/core_input_mouse.lua
new file mode 100644
index 00000000..35ca8e73
--- /dev/null
+++ b/examples/core_input_mouse.lua
@@ -0,0 +1,54 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Mouse input
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse input")
+
+local ballPosition = Vector2(-100.0, -100.0)
+local ballColor = DARKBLUE
+
+SetTargetFPS(60) -- Set target frames-per-second
+-----------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ------------------------------------------------------------------------------------
+ ballPosition = GetMousePosition()
+
+ if (IsMouseButtonPressed(MOUSE.LEFT_BUTTON)) then ballColor = MAROON
+ elseif (IsMouseButtonPressed(MOUSE.MIDDLE_BUTTON)) then ballColor = LIME
+ elseif (IsMouseButtonPressed(MOUSE.RIGHT_BUTTON)) then ballColor = DARKBLUE
+ end
+ ------------------------------------------------------------------------------------
+
+ -- Draw
+ ------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawCircleV(ballPosition, 40, ballColor)
+
+ DrawText("move ball with mouse and click mouse button to change color", 10, 10, 20, DARKGRAY)
+
+ EndDrawing()
+ ------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+----------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+---------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_mouse_wheel.lua b/examples/core_mouse_wheel.lua
new file mode 100644
index 00000000..92e0a160
--- /dev/null
+++ b/examples/core_mouse_wheel.lua
@@ -0,0 +1,50 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] examples - Mouse wheel
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - mouse wheel")
+
+local boxPositionY = screenHeight/2 - 40
+local scrollSpeed = 4 -- Scrolling speed in pixels
+
+SetTargetFPS(60) -- Set target frames-per-second
+----------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ------------------------------------------------------------------------------------
+ boxPositionY = boxPositionY - (GetMouseWheelMove()*scrollSpeed)
+ ------------------------------------------------------------------------------------
+
+ -- Draw
+ ------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawRectangle(screenWidth/2 - 40, boxPositionY, 80, 80, MAROON)
+
+ DrawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, GRAY)
+ DrawText(string.format("Box position Y: %03i", boxPositionY), 10, 40, 20, LIGHTGRAY)
+
+ EndDrawing()
+ ------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+----------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+---------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_oculus_rift.lua b/examples/core_oculus_rift.lua
new file mode 100644
index 00000000..2626d178
--- /dev/null
+++ b/examples/core_oculus_rift.lua
@@ -0,0 +1,73 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Oculus Rift CV1
+--
+-- NOTE: Example requires linkage with LibOVR
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 1080
+local screenHeight = 600
+
+-- NOTE: screenWidth/screenHeight should match VR device aspect ratio
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - oculus rift")
+
+-- NOTE: If device is not available, it fallbacks to default device (simulator)
+InitVrDevice(VrDevice.OCULUS_RIFT_CV1) -- Init VR device (Oculus Rift CV1)
+
+-- Define the camera to look into our 3d world
+local camera = {}
+camera.position = Vector3(5.0, 5.0, 5.0) -- Camera position
+camera.target = Vector3(0.0, 0.0, 0.0) -- Camera looking at point
+camera.up = Vector3(0.0, 1.0, 0.0) -- Camera up vector (rotation towards target)
+camera.fovy = 60.0 -- Camera field-of-view Y
+
+local cubePosition = Vector3(0.0, 0.0, 0.0)
+
+SetTargetFPS(90) -- Set our game to run at 90 frames-per-second
+----------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ------------------------------------------------------------------------------------
+ UpdateVrTracking()
+
+ if (IsKeyPressed(KEY.SPACE)) then ToggleVrMode() end
+ ------------------------------------------------------------------------------------
+
+ -- Draw
+ ------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawCube(cubePosition, 2.0, 2.0, 2.0, RED)
+ DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON)
+
+ DrawGrid(10, 1.0)
+
+ End3dMode()
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+----------------------------------------------------------------------------------------
+CloseVrDevice() -- Close VR device
+
+CloseWindow() -- Close window and OpenGL context
+---------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_random_values.lua b/examples/core_random_values.lua
new file mode 100644
index 00000000..b80ab9e2
--- /dev/null
+++ b/examples/core_random_values.lua
@@ -0,0 +1,56 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Generate random values
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - generate random values")
+
+local framesCounter = 0 -- Variable used to count frames
+
+local randValue = GetRandomValue(-8, 5) -- Get a random integer number between -8 and 5 (both included)
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+----------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ------------------------------------------------------------------------------------
+ framesCounter = framesCounter + 1
+
+ -- Every two seconds (120 frames) a new random value is generated
+ if (((framesCounter/120)%2) == 1) then
+ randValue = GetRandomValue(-8, 5)
+ framesCounter = 0
+ end
+ ------------------------------------------------------------------------------------
+
+ -- Draw
+ ------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("Every 2 seconds a new random value is generated:", 130, 100, 20, MAROON)
+
+ DrawText(string.format("%i", randValue), 360, 180, 80, LIGHTGRAY)
+
+ EndDrawing()
+ ------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+----------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+---------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_storage_values.lua b/examples/core_storage_values.lua
new file mode 100644
index 00000000..878b90e4
--- /dev/null
+++ b/examples/core_storage_values.lua
@@ -0,0 +1,74 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - Storage save/load values
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- NOTE: Storage positions must start with 0, directly related to file memory layout
+STORAGE_SCORE = 0
+STORAGE_HISCORE = 1
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - storage save/load values")
+
+local score = 0
+local hiscore = 0
+
+local framesCounter = 0
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsKeyPressed(KEY.R)) then
+ score = GetRandomValue(1000, 2000)
+ hiscore = GetRandomValue(2000, 4000)
+ end
+
+ if (IsKeyPressed(KEY.ENTER)) then
+ StorageSaveValue(STORAGE_SCORE, score)
+ StorageSaveValue(STORAGE_HISCORE, hiscore)
+ elseif (IsKeyPressed(KEY.SPACE)) then
+ -- NOTE: If requested position could not be found, value 0 is returned
+ score = StorageLoadValue(STORAGE_SCORE)
+ hiscore = StorageLoadValue(STORAGE_HISCORE)
+ end
+
+ framesCounter = framesCounter + 1
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText(string.format("SCORE: %i", score), 280, 130, 40, MAROON)
+ DrawText(string.format("HI-SCORE: %i", hiscore), 210, 200, 50, BLACK)
+
+ DrawText(string.format("frames: %i", framesCounter), 10, 10, 20, LIME)
+
+ DrawText("Press R to generate random numbers", 220, 40, 20, LIGHTGRAY)
+ DrawText("Press ENTER to SAVE values", 250, 310, 20, LIGHTGRAY)
+ DrawText("Press SPACE to LOAD values", 252, 350, 20, LIGHTGRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/core_world_screen.lua b/examples/core_world_screen.lua
new file mode 100644
index 00000000..51f2cdbf
--- /dev/null
+++ b/examples/core_world_screen.lua
@@ -0,0 +1,69 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [core] example - World to screen
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera free")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local cubePosition = Vector3(0.0, 0.0, 0.0)
+
+local cubeScreenPosition = Vector2(0, 0)
+
+SetCameraMode(CameraMode.FREE) -- Set a free camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraTarget(camera.target) -- Set internal camera target to match our camera target
+SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+----------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+
+ -- Calculate cube screen space position (with a little offset to be in top)
+ cubeScreenPosition = GetWorldToScreen(Vector3(cubePosition.x, cubePosition.y + 2.5, cubePosition.z), camera)
+ ------------------------------------------------------------------------------------
+
+ -- Draw
+ ------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawCube(cubePosition, 2.0, 2.0, 2.0, RED)
+ DrawCubeWires(cubePosition, 2.0, 2.0, 2.0, MAROON)
+
+ DrawGrid(10, 1.0)
+
+ End3dMode()
+
+ DrawText("Enemy: 100 / 100", cubeScreenPosition.x//1 - MeasureText("Enemy: 100 / 100", 20)//2, cubeScreenPosition.y//1, 20, BLACK)
+ DrawText("Text is always on top of the cube", (screenWidth - MeasureText("Text is always on top of the cube", 20))//2, 25, 20, GRAY)
+
+ EndDrawing()
+ ------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+----------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+---------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/models_billboard.lua b/examples/models_billboard.lua
new file mode 100644
index 00000000..457198e6
--- /dev/null
+++ b/examples/models_billboard.lua
@@ -0,0 +1,65 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [models] example - Drawing billboards
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [models] example - drawing billboards")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(5.0, 4.0, 5.0), Vector3(0.0, 2.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local bill = LoadTexture("resources/billboard.png") -- Our texture billboard
+local billPosition = Vector3(0.0, 2.0, 0.0) -- Position where draw billboard
+
+SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraTarget(camera.target) -- Set internal camera target to match our camera target
+SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawBillboard(camera, bill, billPosition, 2.0, WHITE)
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ End3dMode()
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(bill) -- Unload texture
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/models_box_collisions.lua b/examples/models_box_collisions.lua
new file mode 100644
index 00000000..4a3107b9
--- /dev/null
+++ b/examples/models_box_collisions.lua
@@ -0,0 +1,115 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [models] example - Detect basic 3d collisions (box vs sphere vs box)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [models] example - box collisions")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local playerPosition = Vector3(0.0, 1.0, 2.0)
+local playerSize = Vector3(1.0, 2.0, 1.0)
+local playerColor = GREEN
+
+local enemyBoxPos = Vector3(-4.0, 1.0, 0.0)
+local enemyBoxSize = Vector3(2.0, 2.0, 2.0)
+
+local enemySpherePos = Vector3(4.0, 0.0, 0.0)
+local enemySphereSize = 1.5
+
+local collision = false
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+
+ -- Move player
+ if (IsKeyDown(KEY.RIGHT)) then playerPosition.x = playerPosition.x + 0.2
+ elseif (IsKeyDown(KEY.LEFT)) then playerPosition.x = playerPosition.x - 0.2
+ elseif (IsKeyDown(KEY.DOWN)) then playerPosition.z = playerPosition.z + 0.2
+ elseif (IsKeyDown(KEY.UP)) then playerPosition.z = playerPosition.z - 0.2 end
+
+ collision = false
+
+ -- Check collisions player vs enemy-box
+ if (CheckCollisionBoxes(
+ BoundingBox(Vector3(playerPosition.x - playerSize.x/2,
+ playerPosition.y - playerSize.y/2,
+ playerPosition.z - playerSize.z/2),
+ Vector3(playerPosition.x + playerSize.x/2,
+ playerPosition.y + playerSize.y/2,
+ playerPosition.z + playerSize.z/2)),
+ BoundingBox(Vector3(enemyBoxPos.x - enemyBoxSize.x/2,
+ enemyBoxPos.y - enemyBoxSize.y/2,
+ enemyBoxPos.z - enemyBoxSize.z/2),
+ Vector3(enemyBoxPos.x + enemyBoxSize.x/2,
+ enemyBoxPos.y + enemyBoxSize.y/2,
+ enemyBoxPos.z + enemyBoxSize.z/2)))) then collision = true
+ end
+
+ -- Check collisions player vs enemy-sphere
+ if (CheckCollisionBoxSphere(
+ BoundingBox(Vector3(playerPosition.x - playerSize.x/2,
+ playerPosition.y - playerSize.y/2,
+ playerPosition.z - playerSize.z/2),
+ Vector3(playerPosition.x + playerSize.x/2,
+ playerPosition.y + playerSize.y/2,
+ playerPosition.z + playerSize.z/2)),
+ enemySpherePos, enemySphereSize)) then collision = true
+ end
+
+ if (collision) then playerColor = RED
+ else playerColor = GREEN end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ -- Draw enemy-box
+ DrawCube(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, GRAY)
+ DrawCubeWires(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, DARKGRAY)
+
+ -- Draw enemy-sphere
+ DrawSphere(enemySpherePos, enemySphereSize, GRAY)
+ DrawSphereWires(enemySpherePos, enemySphereSize, 16, 16, DARKGRAY)
+
+ -- Draw player
+ DrawCubeV(playerPosition, playerSize, playerColor)
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ End3dMode()
+
+ DrawText("Move player with cursors to collide", 220, 40, 20, GRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/models_cubicmap.c b/examples/models_cubicmap.c
index 89bc75cf..df700d65 100644
--- a/examples/models_cubicmap.c
+++ b/examples/models_cubicmap.c
@@ -35,19 +35,17 @@ int main()
UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM
- SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
- SetCameraPosition(camera.position); // Set internal camera position to match our custom camera position
- SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
+ SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
- SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
- while (!WindowShouldClose()) // Detect window close button or ESC key
+ while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
- UpdateCamera(&camera); // Update internal camera and our camera
+ UpdateCamera(&camera); // Update internal camera and our camera
//----------------------------------------------------------------------------------
// Draw
diff --git a/examples/models_cubicmap.lua b/examples/models_cubicmap.lua
new file mode 100644
index 00000000..bae3bac2
--- /dev/null
+++ b/examples/models_cubicmap.lua
@@ -0,0 +1,79 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [models] example - Cubicmap loading and drawing
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [models] example - cubesmap loading and drawing")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(16.0, 14.0, 16.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local image = LoadImage("resources/cubicmap.png") -- Load cubicmap image (RAM)
+local cubicmap = LoadTextureFromImage(image) -- Convert image to texture to display (VRAM)
+local map = LoadCubicmap(image) -- Load cubicmap model (generate model from image)
+
+-- NOTE: By default each cube is mapped to one part of texture atlas
+local texture = LoadTexture("resources/cubicmap_atlas.png") -- Load map texture
+map.material.texDiffuse = texture -- Set map diffuse texture
+
+local mapPosition = Vector3(-16.0, 0.0, -8.0) -- Set model position
+
+UnloadImage(image) -- Unload cubesmap image from RAM, already uploaded to VRAM
+
+SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our custom camera position
+SetCameraFovy(camera.fovy) -- Set internal camera field-of-view Y
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawModel(map, mapPosition, 1.0, WHITE)
+
+ End3dMode()
+
+ DrawTextureEx(cubicmap, (Vector2)(screenWidth - cubicmap.width*4 - 20, 20), 0.0, 4.0, WHITE)
+ DrawRectangleLines(screenWidth - cubicmap.width*4 - 20, 20, cubicmap.width*4, cubicmap.height*4, GREEN)
+
+ DrawText("cubicmap image used to", 658, 90, 10, GRAY)
+ DrawText("generate map 3d model", 658, 104, 10, GRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(cubicmap) -- Unload cubicmap texture
+UnloadTexture(texture) -- Unload map texture
+UnloadModel(map) -- Unload map model
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/models_geometric_shapes.lua b/examples/models_geometric_shapes.lua
new file mode 100644
index 00000000..0ce08e9f
--- /dev/null
+++ b/examples/models_geometric_shapes.lua
@@ -0,0 +1,67 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [models] example - Draw some basic geometric shapes (cube, sphere, cylinder...)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [models] example - geometric shapes")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(0.0, 10.0, 10.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera) -- ERROR: Lua Error: attempt to index a number value
+
+ DrawCube(Vector3(-4.0, 0.0, 2.0), 2.0, 5.0, 2.0, RED)
+ DrawCubeWires(Vector3(-4.0, 0.0, 2.0), 2.0, 5.0, 2.0, GOLD)
+ DrawCubeWires(Vector3(-4.0, 0.0, -2.0), 3.0, 6.0, 2.0, MAROON)
+
+ DrawSphere(Vector3(-1.0, 0.0, -2.0), 1.0, GREEN)
+ DrawSphereWires(Vector3(1.0, 0.0, 2.0), 2.0, 16, 16, LIME)
+
+ DrawCylinder(Vector3(4.0, 0.0, -2.0), 1.0, 2.0, 3.0, 4, SKYBLUE)
+ DrawCylinderWires(Vector3(4.0, 0.0, -2.0), 1.0, 2.0, 3.0, 4, DARKBLUE)
+ DrawCylinderWires(Vector3(4.5, -1.0, 2.0), 1.0, 1.0, 2.0, 6, BROWN)
+
+ DrawCylinder(Vector3(1.0, 0.0, -4.0), 0.0, 1.5, 3.0, 8, GOLD)
+ DrawCylinderWires(Vector3(1.0, 0.0, -4.0), 0.0, 1.5, 3.0, 8, PINK)
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ End3dMode()
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/models_heightmap.lua b/examples/models_heightmap.lua
new file mode 100644
index 00000000..4240f8b7
--- /dev/null
+++ b/examples/models_heightmap.lua
@@ -0,0 +1,73 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [models] example - Heightmap loading and drawing
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing")
+
+-- Define our custom camera to look into our 3d world
+local camera = Camera(Vector3(18.0, 16.0, 18.0), Vector3(0.0, 0.0, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local image = LoadImage("resources/heightmap.png") -- Load heightmap image (RAM)
+local texture = LoadTextureFromImage(image) -- Convert image to texture (VRAM)
+local map = LoadHeightmap(image, Vector3(16, 8, 16)) -- Load heightmap model with defined size
+map.material.texDiffuse = texture -- Set map diffuse texture
+local mapPosition = Vector3(-8.0, 0.0, -8.0) -- Set model position (depends on model scaling!)
+
+UnloadImage(image) -- Unload heightmap image from RAM, already uploaded to VRAM
+
+SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our custom camera position
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+----------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ -- NOTE: Model is scaled to 1/4 of its original size (128x128 units)
+ DrawModel(map, mapPosition, 1.0, RED)
+
+ DrawGrid(20, 1.0)
+
+ End3dMode()
+
+ DrawTexture(texture, screenWidth - texture.width - 20, 20, WHITE)
+ DrawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, GREEN)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(texture) -- Unload texture
+UnloadModel(map) -- Unload model
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/models_obj_loading.lua b/examples/models_obj_loading.lua
new file mode 100644
index 00000000..7e5c7c4b
--- /dev/null
+++ b/examples/models_obj_loading.lua
@@ -0,0 +1,67 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [models] example - Load and draw a 3d model (OBJ)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [models] example - obj model loading")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model
+local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture
+dwarf.material.texDiffuse = texture -- Set dwarf model diffuse texture
+local position = Vector3(0.0, 0.0, 0.0) -- Set model position
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- ...
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ DrawGizmo(position) -- Draw gizmo
+
+ End3dMode()
+
+ DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(texture) -- Unload texture
+UnloadModel(dwarf) -- Unload model
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/physics_basic_rigidbody.c b/examples/physics_basic_rigidbody.c
index 75720c97..87316a98 100644
--- a/examples/physics_basic_rigidbody.c
+++ b/examples/physics_basic_rigidbody.c
@@ -5,9 +5,16 @@
* This example has been created using raylib 1.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
+* NOTE:
+* Physac requires multi-threading, when InitPhysics() a second thread is created to manage
+* physics calculations. To accomplish that, physac uses pthread Win32 library that can be
+* found inside raylib/src/external/pthread directory.
*
-* Compile example using:
-* cmd /c IF NOT EXIST pthreadGC2.dll copy C:\raylib\raylib\src\external\pthread\pthreadGC2.dll $(CURRENT_DIRECTORY) /Y
+* Add pthread library when compiling physac example:
+* gcc -o $(NAME_PART).exe $(FILE_NAME) $(RAYLIB_DIR)\raylib_icon -L../src/external/pthread/lib \
+* -I../src -I../src/external/pthread/include -lraylib -lglfw3 -lopengl32 -lgdi32 -lpthreadGC2 -std=c99 -Wall
+*
+* Note that pthreadGC2.dll must be also copied to project directory!
*
* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
*
diff --git a/examples/physics_forces.c b/examples/physics_forces.c
index efe8e240..e45cb44c 100644
--- a/examples/physics_forces.c
+++ b/examples/physics_forces.c
@@ -5,10 +5,16 @@
* This example has been created using raylib 1.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
-* NOTE: This example requires raylib module [rlgl]
+* NOTE:
+* Physac requires multi-threading, when InitPhysics() a second thread is created to manage
+* physics calculations. To accomplish that, physac uses pthread Win32 library that can be
+* found inside raylib/src/external/pthread directory.
*
-* Compile example using:
-* cmd /c IF NOT EXIST pthreadGC2.dll copy C:\raylib\raylib\src\external\pthread\pthreadGC2.dll $(CURRENT_DIRECTORY) /Y
+* Add pthread library when compiling physac example:
+* gcc -o $(NAME_PART).exe $(FILE_NAME) $(RAYLIB_DIR)\raylib_icon -L../src/external/pthread/lib \
+* -I../src -I../src/external/pthread/include -lraylib -lglfw3 -lopengl32 -lgdi32 -lpthreadGC2 -std=c99 -Wall
+*
+* Note that pthreadGC2.dll must be also copied to project directory!
*
* Copyright (c) 2016 Victor Fisac and Ramon Santamaria (@raysan5)
*
diff --git a/examples/resources/audio/2t2m_spa.xm b/examples/resources/audio/2t2m_spa.xm
deleted file mode 100644
index fa416ef2..00000000
--- a/examples/resources/audio/2t2m_spa.xm
+++ /dev/null
Binary files differ
diff --git a/examples/resources/audio/chiptun1.mod b/examples/resources/audio/chiptun1.mod
new file mode 100644
index 00000000..00d16885
--- /dev/null
+++ b/examples/resources/audio/chiptun1.mod
Binary files differ
diff --git a/examples/resources/audio/mini1111.xm b/examples/resources/audio/mini1111.xm
new file mode 100644
index 00000000..a185c1a2
--- /dev/null
+++ b/examples/resources/audio/mini1111.xm
Binary files differ
diff --git a/examples/resources/shaders/glsl100/bloom.fs b/examples/resources/shaders/glsl100/bloom.fs
index 128736f2..a8e1d20f 100644
--- a/examples/resources/shaders/glsl100/bloom.fs
+++ b/examples/resources/shaders/glsl100/bloom.fs
@@ -8,30 +8,32 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+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);
- vec4 tc = vec4(0);
+ vec2 sizeFactor = vec2(1)/size*quality;
+
+ // Texel color fetching from texture sampler
+ vec4 source = texture2D(texture0, fragTexCoord);
- for (int i = -4; i < 4; i++)
+ const int range = 2; // should be = (samples - 1)/2;
+
+ for (int x = -range; x <= range; x++)
{
- for (int j = -3; j < 3; j++)
+ for (int y = -range; y <= range; y++)
{
- sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25;
+ sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor);
}
}
-
- // Texel color fetching from texture sampler
- vec4 texelColor = texture2D(texture0, fragTexCoord);
-
+
// Calculate final fragment color
- if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
- else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
- else tc = sum*sum*0.0075 + texelColor;
-
- gl_FragColor = tc;
+ gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse;
} \ No newline at end of file
diff --git a/examples/resources/shaders/glsl100/standard.fs b/examples/resources/shaders/glsl100/standard.fs
new file mode 100644
index 00000000..6ce2a186
--- /dev/null
+++ b/examples/resources/shaders/glsl100/standard.fs
@@ -0,0 +1,161 @@
+#version 100
+
+precision mediump float;
+
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+uniform sampler2D texture0;
+uniform sampler2D texture1;
+uniform sampler2D texture2;
+
+uniform vec4 colAmbient;
+uniform vec4 colDiffuse;
+uniform vec4 colSpecular;
+uniform float glossiness;
+
+uniform int useNormal;
+uniform int useSpecular;
+
+uniform mat4 modelMatrix;
+uniform vec3 viewDir;
+
+struct Light {
+ int enabled;
+ int type;
+ vec3 position;
+ vec3 direction;
+ vec4 diffuse;
+ float intensity;
+ float radius;
+ float coneAngle;
+};
+
+const int maxLights = 8;
+uniform Light lights[maxLights];
+
+vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s)
+{
+/*
+ vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1.0));
+ vec3 surfaceToLight = l.position - surfacePos;
+
+ // Diffuse shading
+ float brightness = clamp(float(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n))), 0.0, 1.0);
+ float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity;
+
+ // Specular shading
+ float spec = 0.0;
+ if (diff > 0.0)
+ {
+ vec3 h = normalize(-l.direction + v);
+ spec = pow(dot(n, h), 3.0 + glossiness)*s;
+ }
+
+ return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
+*/
+ return vec3(0.5);
+}
+
+vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s)
+{
+/*
+ vec3 lightDir = normalize(-l.direction);
+
+ // Diffuse shading
+ float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity;
+
+ // Specular shading
+ float spec = 0.0;
+ if (diff > 0.0)
+ {
+ vec3 h = normalize(lightDir + v);
+ spec = pow(dot(n, h), 3.0 + glossiness)*s;
+ }
+
+ // Combine results
+ return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);
+*/
+ return vec3(0.5);
+}
+
+vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s)
+{
+/*
+ vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));
+ vec3 lightToSurface = normalize(surfacePos - l.position);
+ vec3 lightDir = normalize(-l.direction);
+
+ // Diffuse shading
+ float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity;
+
+ // Spot attenuation
+ float attenuation = clamp(float(dot(n, lightToSurface)), 0.0, 1.0);
+ attenuation = dot(lightToSurface, -lightDir);
+
+ float lightToSurfaceAngle = degrees(acos(attenuation));
+ if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;
+
+ float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;
+
+ // Combine diffuse and attenuation
+ float diffAttenuation = diff*attenuation;
+
+ // Specular shading
+ float spec = 0.0;
+ if (diffAttenuation > 0.0)
+ {
+ vec3 h = normalize(lightDir + v);
+ spec = pow(dot(n, h), 3.0 + glossiness)*s;
+ }
+
+ return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
+*/
+ return vec3(0.5);
+}
+
+void main()
+{
+ // Calculate fragment normal in screen space
+ // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale)
+ mat3 normalMatrix = mat3(modelMatrix);
+ vec3 normal = normalize(normalMatrix*fragNormal);
+
+ // Normalize normal and view direction vectors
+ vec3 n = normalize(normal);
+ vec3 v = normalize(viewDir);
+
+ // Calculate diffuse texture color fetching
+ vec4 texelColor = texture2D(texture0, fragTexCoord);
+ vec3 lighting = colAmbient.rgb;
+
+ // Calculate normal texture color fetching or set to maximum normal value by default
+ if (useNormal == 1)
+ {
+ n *= texture2D(texture1, fragTexCoord).rgb;
+ n = normalize(n);
+ }
+
+ // Calculate specular texture color fetching or set to maximum specular value by default
+ float spec = 1.0;
+ if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r);
+
+ for (int i = 0; i < maxLights; i++)
+ {
+ // Check if light is enabled
+ if (lights[i].enabled == 1)
+ {
+ // Calculate lighting based on light type
+ if(lights[i].type == 0) lighting += ComputeLightPoint(lights[i], n, v, spec);
+ else if(lights[i].type == 1) lighting += ComputeLightDirectional(lights[i], n, v, spec);
+ else if(lights[i].type == 2) lighting += ComputeLightSpot(lights[i], n, v, spec);
+
+ // NOTE: It seems that too many ComputeLight*() operations inside for loop breaks the shader on RPI
+ }
+ }
+
+ // Calculate final fragment color
+ gl_FragColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a);
+}
diff --git a/examples/resources/shaders/glsl100/standard.vs b/examples/resources/shaders/glsl100/standard.vs
new file mode 100644
index 00000000..49c5a3eb
--- /dev/null
+++ b/examples/resources/shaders/glsl100/standard.vs
@@ -0,0 +1,23 @@
+#version 100
+
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec2 vertexTexCoord;
+attribute vec4 vertexColor;
+
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+uniform mat4 mvpMatrix;
+
+void main()
+{
+ fragPosition = vertexPosition;
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ fragNormal = vertexNormal;
+
+ gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+} \ No newline at end of file
diff --git a/examples/resources/shaders/glsl330/bloom.fs b/examples/resources/shaders/glsl330/bloom.fs
index 0307bc06..333d5b05 100644
--- a/examples/resources/shaders/glsl330/bloom.fs
+++ b/examples/resources/shaders/glsl330/bloom.fs
@@ -6,33 +6,35 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// 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);
- vec4 tc = vec4(0);
+ vec2 sizeFactor = vec2(1)/size*quality;
+
+ // Texel color fetching from texture sampler
+ vec4 source = texture(texture0, fragTexCoord);
+
+ const int range = 2; // should be = (samples - 1)/2;
- for (int i = -4; i < 4; i++)
+ for (int x = -range; x <= range; x++)
{
- for (int j = -3; j < 3; j++)
+ for (int y = -range; y <= range; y++)
{
- sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25;
+ sum += texture(texture0, fragTexCoord + vec2(x, y)*sizeFactor);
}
}
-
- // Texel color fetching from texture sampler
- vec4 texelColor = texture(texture0, fragTexCoord);
-
- // Calculate final fragment color
- if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
- else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
- else tc = sum*sum*0.0075 + texelColor;
- finalColor = tc;
+ // Calculate final fragment color
+ finalColor = ((sum/(samples*samples)) + source)*colDiffuse;
} \ No newline at end of file
diff --git a/examples/resources/shaders/glsl330/standard.fs b/examples/resources/shaders/glsl330/standard.fs
new file mode 100644
index 00000000..14497839
--- /dev/null
+++ b/examples/resources/shaders/glsl330/standard.fs
@@ -0,0 +1,150 @@
+#version 330
+
+in vec3 fragPosition;
+in vec2 fragTexCoord;
+in vec4 fragColor;
+in vec3 fragNormal;
+
+out vec4 finalColor;
+
+uniform sampler2D texture0;
+uniform sampler2D texture1;
+uniform sampler2D texture2;
+
+uniform vec4 colAmbient;
+uniform vec4 colDiffuse;
+uniform vec4 colSpecular;
+uniform float glossiness;
+
+uniform int useNormal;
+uniform int useSpecular;
+
+uniform mat4 modelMatrix;
+uniform vec3 viewDir;
+
+struct Light {
+ int enabled;
+ int type;
+ vec3 position;
+ vec3 direction;
+ vec4 diffuse;
+ float intensity;
+ float radius;
+ float coneAngle;
+};
+
+const int maxLights = 8;
+uniform Light lights[maxLights];
+
+vec3 ComputeLightPoint(Light l, vec3 n, vec3 v, float s)
+{
+ vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));
+ vec3 surfaceToLight = l.position - surfacePos;
+
+ // Diffuse shading
+ float brightness = clamp(float(dot(n, surfaceToLight)/(length(surfaceToLight)*length(n))), 0.0, 1.0);
+ float diff = 1.0/dot(surfaceToLight/l.radius, surfaceToLight/l.radius)*brightness*l.intensity;
+
+ // Specular shading
+ float spec = 0.0;
+ if (diff > 0.0)
+ {
+ vec3 h = normalize(-l.direction + v);
+ spec = pow(dot(n, h), 3.0 + glossiness)*s;
+ }
+
+ return (diff*l.diffuse.rgb + spec*colSpecular.rgb);
+}
+
+vec3 ComputeLightDirectional(Light l, vec3 n, vec3 v, float s)
+{
+ vec3 lightDir = normalize(-l.direction);
+
+ // Diffuse shading
+ float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity;
+
+ // Specular shading
+ float spec = 0.0;
+ if (diff > 0.0)
+ {
+ vec3 h = normalize(lightDir + v);
+ spec = pow(dot(n, h), 3.0 + glossiness)*s;
+ }
+
+ // Combine results
+ return (diff*l.intensity*l.diffuse.rgb + spec*colSpecular.rgb);
+}
+
+vec3 ComputeLightSpot(Light l, vec3 n, vec3 v, float s)
+{
+ vec3 surfacePos = vec3(modelMatrix*vec4(fragPosition, 1));
+ vec3 lightToSurface = normalize(surfacePos - l.position);
+ vec3 lightDir = normalize(-l.direction);
+
+ // Diffuse shading
+ float diff = clamp(float(dot(n, lightDir)), 0.0, 1.0)*l.intensity;
+
+ // Spot attenuation
+ float attenuation = clamp(float(dot(n, lightToSurface)), 0.0, 1.0);
+ attenuation = dot(lightToSurface, -lightDir);
+
+ float lightToSurfaceAngle = degrees(acos(attenuation));
+ if (lightToSurfaceAngle > l.coneAngle) attenuation = 0.0;
+
+ float falloff = (l.coneAngle - lightToSurfaceAngle)/l.coneAngle;
+
+ // Combine diffuse and attenuation
+ float diffAttenuation = diff*attenuation;
+
+ // Specular shading
+ float spec = 0.0;
+ if (diffAttenuation > 0.0)
+ {
+ vec3 h = normalize(lightDir + v);
+ spec = pow(dot(n, h), 3.0 + glossiness)*s;
+ }
+
+ return (falloff*(diffAttenuation*l.diffuse.rgb + spec*colSpecular.rgb));
+}
+
+void main()
+{
+ // Calculate fragment normal in screen space
+ // NOTE: important to multiply model matrix by fragment normal to apply model transformation (rotation and scale)
+ mat3 normalMatrix = mat3(modelMatrix);
+ vec3 normal = normalize(normalMatrix*fragNormal);
+
+ // Normalize normal and view direction vectors
+ vec3 n = normalize(normal);
+ vec3 v = normalize(viewDir);
+
+ // Calculate diffuse texture color fetching
+ vec4 texelColor = texture(texture0, fragTexCoord);
+ vec3 lighting = colAmbient.rgb;
+
+ // Calculate normal texture color fetching or set to maximum normal value by default
+ if (useNormal == 1)
+ {
+ n *= texture(texture1, fragTexCoord).rgb;
+ n = normalize(n);
+ }
+
+ // Calculate specular texture color fetching or set to maximum specular value by default
+ float spec = 1.0;
+ if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);
+
+ for (int i = 0; i < maxLights; i++)
+ {
+ // Check if light is enabled
+ if (lights[i].enabled == 1)
+ {
+ // Calculate lighting based on light type
+ if (lights[i].type == 0) lighting += ComputeLightPoint(lights[i], n, v, spec);
+ else if (lights[i].type == 1) lighting += ComputeLightDirectional(lights[i], n, v, spec);
+ else if (lights[i].type == 2) lighting += ComputeLightSpot(lights[i], n, v, spec);
+ }
+ }
+
+ // Calculate final fragment color
+ finalColor = vec4(texelColor.rgb*lighting*colDiffuse.rgb, texelColor.a*colDiffuse.a);
+}
diff --git a/examples/resources/shaders/glsl330/standard.vs b/examples/resources/shaders/glsl330/standard.vs
new file mode 100644
index 00000000..fc0a5ff4
--- /dev/null
+++ b/examples/resources/shaders/glsl330/standard.vs
@@ -0,0 +1,23 @@
+#version 330
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+in vec2 vertexTexCoord;
+in vec4 vertexColor;
+
+out vec3 fragPosition;
+out vec2 fragTexCoord;
+out vec4 fragColor;
+out vec3 fragNormal;
+
+uniform mat4 mvpMatrix;
+
+void main()
+{
+ fragPosition = vertexPosition;
+ fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ fragNormal = vertexNormal;
+
+ gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
+} \ No newline at end of file
diff --git a/examples/rlua_execute_file.c b/examples/rlua_execute_file.c
new file mode 100644
index 00000000..71720313
--- /dev/null
+++ b/examples/rlua_execute_file.c
@@ -0,0 +1,90 @@
+/*******************************************************************************************
+*
+* raylib [rlua] example - Lua file execution
+*
+* NOTE: This example requires Lua library (http://luabinaries.sourceforge.net/download.html)
+*
+* Compile example using:
+* gcc -o $(NAME_PART).exe $(FILE_NAME) $(RAYLIB_DIR)\raylib_icon /
+* -I../src -I../src/external/lua/include -L../src/external/lua/lib /
+* -lraylib -lglfw3 -lopengl32 -lopenal32 -llua53 -lgdi32 -std=c99
+*
+* This example has been created using raylib 1.6 (www.raylib.com)
+* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
+*
+********************************************************************************************/
+
+#include "raylib.h"
+
+#define RLUA_IMPLEMENTATION
+#include "rlua.h"
+
+int main()
+{
+ // Initialization
+ //--------------------------------------------------------------------------------------
+ InitLuaDevice();
+ //--------------------------------------------------------------------------------------
+
+ // ExecuteLuaFile("core_basic_window.lua"); // OK!
+ // ExecuteLuaFile("core_input_keys.lua"); // OK!
+ // ExecuteLuaFile("core_input_mouse.lua"); // OK!
+ // ExecuteLuaFile("core_mouse_wheel.lua"); // OK!
+ // ExecuteLuaFile("core_input_gamepad.lua"); // OK!
+ // ExecuteLuaFile("core_random_values.lua"); // OK!
+ // ExecuteLuaFile("core_color_select.lua"); // OK!
+ // ExecuteLuaFile("core_drop_files.lua"); // OK!
+ // ExecuteLuaFile("core_storage_values.lua"); // OK!
+ // ExecuteLuaFile("core_gestures_detection.lua"); // OK!
+ // ExecuteLuaFile("core_3d_mode.lua"); // OK!
+ // ExecuteLuaFile("core_3d_picking.lua"); // OK!
+ // ExecuteLuaFile("core_3d_camera_free.lua"); // OK!
+ // ExecuteLuaFile("core_3d_camera_first_person.lua"); // OK!
+ // ExecuteLuaFile("core_2d_camera.lua"); // OK!
+ // ExecuteLuaFile("core_world_screen.lua"); // OK!
+ // ExecuteLuaFile("core_oculus_rift.lua"); // OK!
+ // ExecuteLuaFile("shapes_logo_raylib.lua"); // OK!
+ // ExecuteLuaFile("shapes_basic_shapes.lua"); // OK!
+ // ExecuteLuaFile("shapes_colors_palette.lua"); // OK!
+ // ExecuteLuaFile("shapes_logo_raylib_anim.lua"); // OK! NOTE: Use lua string.sub() instead of raylib SubText()
+ // ExecuteLuaFile("textures_logo_raylib.lua"); // OK!
+ // ExecuteLuaFile("textures_image_loading.lua"); // OK!
+ // ExecuteLuaFile("textures_rectangle.lua"); // OK!
+ // ExecuteLuaFile("textures_srcrec_dstrec.lua"); // OK!
+ // ExecuteLuaFile("textures_to_image.lua"); // OK!
+ // ExecuteLuaFile("textures_raw_data.lua"); // ERROR: LoadImageEx()
+ // ExecuteLuaFile("textures_formats_loading.lua"); // OK!
+ // ExecuteLuaFile("textures_particles_trail_blending.lua"); // OK!
+ // ExecuteLuaFile("textures_image_processing.lua"); // ERROR: GetImageData() --> UpdateTexture()
+ // ExecuteLuaFile("textures_image_drawing.lua"); // OK!
+ // ExecuteLuaFile("text_sprite_fonts.lua"); // OK!
+ // ExecuteLuaFile("text_bmfont_ttf.lua"); // OK!
+ // ExecuteLuaFile("text_rbmf_fonts.lua"); // OK!
+ // ExecuteLuaFile("text_format_text.lua"); // OK! NOTE: Use lua string.format() instead of raylib FormatText()
+ // ExecuteLuaFile("text_font_select.lua"); // OK!
+ // ExecuteLuaFile("text_writing_anim.lua"); // OK!
+ // ExecuteLuaFile("models_geometric_shapes.lua"); // OK!
+ // ExecuteLuaFile("models_box_collisions.lua"); // OK!
+ // ExecuteLuaFile("models_billboard.lua"); // OK!
+ // ExecuteLuaFile("models_obj_loading.lua"); // OK!
+ // ExecuteLuaFile("models_heightmap.lua"); // OK!
+ // ExecuteLuaFile("models_cubicmap.lua"); // OK!
+ // ExecuteLuaFile("shaders_model_shader.lua"); // OK!
+ // ExecuteLuaFile("shaders_shapes_textures.lua"); // OK!
+ // ExecuteLuaFile("shaders_custom_uniform.lua"); // OK!
+ // ExecuteLuaFile("shaders_postprocessing.lua"); // OK!
+ // ExecuteLuaFile("shaders_standard_lighting.lua"); // OK!
+ // ExecuteLuaFile("audio_sound_loading.lua"); // OK!
+ // ExecuteLuaFile("audio_music_stream.lua"); // OK!
+ // ExecuteLuaFile("audio_module_playing.lua"); // OK!
+ // ExecuteLuaFile("audio_raw_stream.lua"); // ERROR: UpdateAudioStream()
+
+ // De-Initialization
+ //--------------------------------------------------------------------------------------
+ CloseLuaDevice(); // Close Lua device and free resources
+ //--------------------------------------------------------------------------------------
+
+ return 0;
+} \ No newline at end of file
diff --git a/examples/shaders_custom_uniform.lua b/examples/shaders_custom_uniform.lua
new file mode 100644
index 00000000..3a8bbae5
--- /dev/null
+++ b/examples/shaders_custom_uniform.lua
@@ -0,0 +1,115 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shaders] example - Apply a postprocessing shader and connect a custom uniform variable
+--
+-- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+-- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+--
+-- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
+-- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
+-- raylib comes with shaders ready for both versions, check raylib/shaders install folder
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available)
+
+InitWindow(screenWidth, screenHeight, "raylib [shaders] example - custom uniform variable")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model
+local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture (diffuse map)
+dwarf.material.texDiffuse = texture -- Set dwarf model diffuse texture
+
+local position = Vector3(0.0, 0.0, 0.0) -- Set model position
+
+local shader = LoadShader("resources/shaders/glsl330/base.vs",
+ "resources/shaders/glsl330/swirl.fs") -- Load postpro shader
+
+-- Get variable (uniform) location on the shader to connect with the program
+-- NOTE: If uniform variable could not be found in the shader, function returns -1
+local swirlCenterLoc = GetShaderLocation(shader, "center")
+
+local swirlCenter = { screenWidth/2, screenHeight/2 }
+
+-- Create a RenderTexture2D to be used for render to texture
+local target = LoadRenderTexture(screenWidth, screenHeight)
+
+-- Setup orbital camera
+SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraTarget(camera.target) -- Set internal camera target to match our camera target
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ local mousePosition = GetMousePosition()
+
+ swirlCenter[1] = mousePosition.x
+ swirlCenter[2] = screenHeight - mousePosition.y
+
+ -- Send new value to the shader to be used on drawing
+ SetShaderValue(shader, swirlCenterLoc, swirlCenter)
+
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ BeginTextureMode(target) -- Enable drawing to texture
+
+ Begin3dMode(camera)
+
+ DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ End3dMode()
+
+ DrawText("TEXT DRAWN IN RENDER TEXTURE", 200, 10, 30, RED)
+
+ EndTextureMode() -- End drawing to texture (now we have a texture available for next passes)
+
+ BeginShaderMode(shader)
+
+ -- NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
+ DrawTextureRec(target.texture, Rectangle(0, 0, target.texture.width, -target.texture.height), Vector2(0, 0), WHITE)
+
+ EndShaderMode()
+
+ DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadShader(shader) -- Unload shader
+UnloadTexture(texture) -- Unload texture
+UnloadModel(dwarf) -- Unload model
+UnloadRenderTexture(target) -- Unload render texture
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shaders_model_shader.c b/examples/shaders_model_shader.c
index a1e00671..a5516eba 100644
--- a/examples/shaders_model_shader.c
+++ b/examples/shaders_model_shader.c
@@ -37,25 +37,22 @@ int main()
Shader shader = LoadShader("resources/shaders/glsl330/base.vs",
"resources/shaders/glsl330/grayscale.fs"); // Load model shader
- dwarf.material.shader = shader; // Set shader effect to 3d model
- dwarf.material.texDiffuse = texture; // Bind texture to model
+ dwarf.material.shader = shader; // Set shader effect to 3d model
+ dwarf.material.texDiffuse = texture; // Bind texture to model
- Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
+ Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position
- // Setup orbital camera
- SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
- SetCameraPosition(camera.position); // Set internal camera position to match our camera position
- SetCameraTarget(camera.target); // Set internal camera target to match our camera target
+ SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
- SetTargetFPS(60); // Set our game to run at 60 frames-per-second
+ SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
- while (!WindowShouldClose()) // Detect window close button or ESC key
+ while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
- UpdateCamera(&camera); // Update internal camera and our camera
+ UpdateCamera(&camera); // Update internal camera and our camera
//----------------------------------------------------------------------------------
// Draw
diff --git a/examples/shaders_model_shader.lua b/examples/shaders_model_shader.lua
new file mode 100644
index 00000000..d1436a7e
--- /dev/null
+++ b/examples/shaders_model_shader.lua
@@ -0,0 +1,85 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shaders] example - Apply a shader to a 3d model
+--
+-- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+-- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+--
+-- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
+-- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
+-- raylib comes with shaders ready for both versions, check raylib/shaders install folder
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available)
+
+InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model
+local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture
+local shader = LoadShader("resources/shaders/glsl330/base.vs",
+ "resources/shaders/glsl330/grayscale.fs") -- Load model shader
+
+dwarf.material.shader = shader -- Set shader effect to 3d model
+dwarf.material.texDiffuse = texture -- Bind texture to model
+
+local position = Vector3(0.0, 0.0, 0.0) -- Set model position
+
+-- Setup orbital camera
+SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraTarget(camera.target) -- Set internal camera target to match our camera target
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ End3dMode()
+
+ DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadShader(shader) -- Unload shader
+UnloadTexture(texture) -- Unload texture
+UnloadModel(dwarf) -- Unload model
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shaders_postprocessing.lua b/examples/shaders_postprocessing.lua
new file mode 100644
index 00000000..f20f31ec
--- /dev/null
+++ b/examples/shaders_postprocessing.lua
@@ -0,0 +1,101 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shaders] example - Apply a postprocessing shader to a scene
+--
+-- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+-- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+--
+-- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
+-- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
+-- raylib comes with shaders ready for both versions, check raylib/shaders install folder
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available)
+
+InitWindow(screenWidth, screenHeight, "raylib [shaders] example - postprocessing shader")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(3.0, 3.0, 3.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model
+local texture = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model texture (diffuse map)
+dwarf.material.texDiffuse = texture -- Set dwarf model diffuse texture
+
+local position = Vector3(0.0, 0.0, 0.0) -- Set model position
+
+local shader = LoadShader("resources/shaders/glsl330/base.vs",
+ "resources/shaders/glsl330/bloom.fs") -- Load postpro shader
+
+-- Create a RenderTexture2D to be used for render to texture
+local target = LoadRenderTexture(screenWidth, screenHeight)
+
+-- Setup orbital camera
+SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraTarget(camera.target) -- Set internal camera target to match our camera target
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ BeginTextureMode(target) -- Enable drawing to texture
+
+ Begin3dMode(camera)
+
+ DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ End3dMode()
+
+ DrawText("HELLO POSTPROCESSING!", 70, 190, 50, RED)
+
+ EndTextureMode() -- End drawing to texture (now we have a texture available for next passes)
+
+ BeginShaderMode(shader)
+
+ -- NOTE: Render texture must be y-flipped due to default OpenGL coordinates (left-bottom)
+ DrawTextureRec(target.texture, Rectangle(0, 0, target.texture.width, -target.texture.height), Vector2(0, 0), WHITE)
+
+ EndShaderMode()
+
+ DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, DARKGRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadShader(shader) -- Unload shader
+UnloadTexture(texture) -- Unload texture
+UnloadModel(dwarf) -- Unload model
+UnloadRenderTexture(target) -- Unload render texture
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shaders_shapes_textures.lua b/examples/shaders_shapes_textures.lua
new file mode 100644
index 00000000..caaeba1a
--- /dev/null
+++ b/examples/shaders_shapes_textures.lua
@@ -0,0 +1,101 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shaders] example - Apply a shader to some shape or texture
+--
+-- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+-- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+--
+-- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
+-- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
+-- raylib comes with shaders ready for both versions, check raylib/shaders install folder
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [shaders] example - shapes and texture shaders")
+
+local sonic = LoadTexture("resources/texture_formats/sonic.png")
+
+-- NOTE: Using GLSL 330 shader version, on OpenGL ES 2.0 use GLSL 100 shader version
+local shader = LoadShader("resources/shaders/glsl330/base.vs",
+ "resources/shaders/glsl330/grayscale.fs")
+
+-- Shader usage is also different than models/postprocessing, shader is just activated when required
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ -- Start drawing with default shader
+
+ DrawText("USING DEFAULT SHADER", 20, 40, 10, RED)
+
+ DrawCircle(80, 120, 35, DARKBLUE)
+ DrawCircleGradient(80, 220, 60, GREEN, SKYBLUE)
+ DrawCircleLines(80, 340, 80, DARKBLUE)
+
+
+ -- Activate our custom shader to be applied on next shapes/textures drawings
+ BeginShaderMode(shader)
+
+ DrawText("USING CUSTOM SHADER", 190, 40, 10, RED)
+
+ DrawRectangle(250 - 60, 90, 120, 60, RED)
+ DrawRectangleGradient(250 - 90, 170, 180, 130, MAROON, GOLD)
+ DrawRectangleLines(250 - 40, 320, 80, 60, ORANGE)
+
+ -- Activate our default shader for next drawings
+ EndShaderMode()
+
+ DrawText("USING DEFAULT SHADER", 370, 40, 10, RED)
+
+ DrawTriangle(Vector2(430, 80),
+ Vector2(430 - 60, 150),
+ Vector2(430 + 60, 150), VIOLET)
+
+ DrawTriangleLines(Vector2(430, 160),
+ Vector2(430 - 20, 230),
+ Vector2(430 + 20, 230), DARKBLUE)
+
+ DrawPoly(Vector2(430, 320), 6, 80, 0, BROWN)
+
+ -- Activate our custom shader to be applied on next shapes/textures drawings
+ BeginShaderMode(shader)
+
+ DrawTexture(sonic, 380, -10, WHITE) -- Using custom shader
+
+ -- Activate our default shader for next drawings
+ EndShaderMode()
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadShader(shader) -- Unload shader
+UnloadTexture(sonic) -- Unload texture
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shaders_standard_lighting.lua b/examples/shaders_standard_lighting.lua
new file mode 100644
index 00000000..2f3700ff
--- /dev/null
+++ b/examples/shaders_standard_lighting.lua
@@ -0,0 +1,114 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shaders] example - Standard lighting (materials and lights)
+--
+-- NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
+-- OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
+--
+-- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
+-- on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
+-- raylib comes with shaders ready for both versions, check raylib/shaders install folder
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+SetConfigFlags(FLAG.MSAA_4X_HINT) -- Enable Multi Sampling Anti Aliasing 4x (if available)
+
+InitWindow(screenWidth, screenHeight, "raylib [shaders] example - model shader")
+
+-- Define the camera to look into our 3d world
+local camera = Camera(Vector3(4.0, 4.0, 4.0), Vector3(0.0, 1.5, 0.0), Vector3(0.0, 1.0, 0.0), 45.0)
+
+local dwarf = LoadModel("resources/model/dwarf.obj") -- Load OBJ model
+local position = Vector3(0.0, 0.0, 0.0) -- Set model position
+
+local material = LoadStandardMaterial()
+
+material.texDiffuse = LoadTexture("resources/model/dwarf_diffuse.png") -- Load model diffuse texture
+material.texNormal = LoadTexture("resources/model/dwarf_normal.png") -- Load model normal texture
+material.texSpecular = LoadTexture("resources/model/dwarf_specular.png") -- Load model specular texture
+material.colDiffuse = WHITE
+material.colAmbient = Color(0, 0, 10, 255)
+material.colSpecular = WHITE
+material.glossiness = 50.0
+
+dwarf.material = material -- Apply material to model
+
+local spotLight = CreateLight(LightType.SPOT, Vector3(3.0, 5.0, 2.0), Color(255, 255, 255, 255))
+spotLight.target = Vector3(0.0, 0.0, 0.0)
+spotLight.intensity = 2.0
+spotLight.diffuse = Color(255, 100, 100, 255)
+spotLight.coneAngle = 60.0
+
+local dirLight = CreateLight(LightType.DIRECTIONAL, Vector3(0.0, -3.0, -3.0), Color(255, 255, 255, 255))
+dirLight.target = Vector3(1.0, -2.0, -2.0)
+dirLight.intensity = 2.0
+dirLight.diffuse = Color(100, 255, 100, 255)
+
+local pointLight = CreateLight(LightType.POINT, Vector3(0.0, 4.0, 5.0), Color(255, 255, 255, 255))
+pointLight.intensity = 2.0
+pointLight.diffuse = Color(100, 100, 255, 255)
+pointLight.radius = 3.0
+
+-- Setup orbital camera
+SetCameraMode(CameraMode.ORBITAL) -- Set an orbital camera mode
+SetCameraPosition(camera.position) -- Set internal camera position to match our camera position
+SetCameraTarget(camera.target) -- Set internal camera target to match our camera target
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ camera = UpdateCamera(camera) -- Update internal camera and our camera
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ Begin3dMode(camera)
+
+ DrawModel(dwarf, position, 2.0, WHITE) -- Draw 3d model with texture
+
+ DrawLight(spotLight) -- Draw spot light
+ DrawLight(dirLight) -- Draw directional light
+ DrawLight(pointLight) -- Draw point light
+
+ DrawGrid(10, 1.0) -- Draw a grid
+
+ End3dMode()
+
+ DrawText("(c) Dwarf 3D model by David Moreno", screenWidth - 200, screenHeight - 20, 10, GRAY)
+
+ DrawFPS(10, 10)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadMaterial(material) -- Unload material and assigned textures
+UnloadModel(dwarf) -- Unload model
+
+-- Destroy all created lights
+DestroyLight(pointLight)
+DestroyLight(dirLight)
+DestroyLight(spotLight)
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shapes_basic_shapes.lua b/examples/shapes_basic_shapes.lua
new file mode 100644
index 00000000..cc943ba3
--- /dev/null
+++ b/examples/shapes_basic_shapes.lua
@@ -0,0 +1,64 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shapes] example - Draw basic shapes 2d (rectangle, circle, line...)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [shapes] example - basic shapes drawing")
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("some basic shapes available on raylib", 20, 20, 20, DARKGRAY)
+
+ DrawLine(18, 42, screenWidth - 18, 42, BLACK)
+
+ DrawCircle(screenWidth/4, 120, 35, DARKBLUE)
+ DrawCircleGradient(screenWidth/4, 220, 60, GREEN, SKYBLUE)
+ DrawCircleLines(screenWidth/4, 340, 80, DARKBLUE)
+
+ DrawRectangle(screenWidth/4*2 - 60, 100, 120, 60, RED)
+ DrawRectangleGradient(screenWidth/4*2 - 90, 170, 180, 130, MAROON, GOLD)
+ DrawRectangleLines(screenWidth/4*2 - 40, 320, 80, 60, ORANGE)
+
+ DrawTriangle(Vector2(screenWidth/4*3, 80),
+ Vector2(screenWidth/4*3 - 60, 150),
+ Vector2(screenWidth/4*3 + 60, 150), VIOLET)
+
+ DrawTriangleLines(Vector2(screenWidth/4*3, 160),
+ Vector2(screenWidth/4*3 - 20, 230),
+ Vector2(screenWidth/4*3 + 20, 230), DARKBLUE)
+
+ DrawPoly(Vector2(screenWidth/4*3, 320), 6, 80, 0, BROWN)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shapes_colors_palette.lua b/examples/shapes_colors_palette.lua
new file mode 100644
index 00000000..e884cd3e
--- /dev/null
+++ b/examples/shapes_colors_palette.lua
@@ -0,0 +1,89 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shapes] example - Draw raylib custom color palette
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib color palette")
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("raylib color palette", 28, 42, 20, BLACK)
+
+ DrawRectangle(26, 80, 100, 100, DARKGRAY)
+ DrawRectangle(26, 188, 100, 100, GRAY)
+ DrawRectangle(26, 296, 100, 100, LIGHTGRAY)
+ DrawRectangle(134, 80, 100, 100, MAROON)
+ DrawRectangle(134, 188, 100, 100, RED)
+ DrawRectangle(134, 296, 100, 100, PINK)
+ DrawRectangle(242, 80, 100, 100, ORANGE)
+ DrawRectangle(242, 188, 100, 100, GOLD)
+ DrawRectangle(242, 296, 100, 100, YELLOW)
+ DrawRectangle(350, 80, 100, 100, DARKGREEN)
+ DrawRectangle(350, 188, 100, 100, LIME)
+ DrawRectangle(350, 296, 100, 100, GREEN)
+ DrawRectangle(458, 80, 100, 100, DARKBLUE)
+ DrawRectangle(458, 188, 100, 100, BLUE)
+ DrawRectangle(458, 296, 100, 100, SKYBLUE)
+ DrawRectangle(566, 80, 100, 100, DARKPURPLE)
+ DrawRectangle(566, 188, 100, 100, VIOLET)
+ DrawRectangle(566, 296, 100, 100, PURPLE)
+ DrawRectangle(674, 80, 100, 100, DARKBROWN)
+ DrawRectangle(674, 188, 100, 100, BROWN)
+ DrawRectangle(674, 296, 100, 100, BEIGE)
+
+
+ DrawText("DARKGRAY", 65, 166, 10, BLACK)
+ DrawText("GRAY", 93, 274, 10, BLACK)
+ DrawText("LIGHTGRAY", 61, 382, 10, BLACK)
+ DrawText("MAROON", 186, 166, 10, BLACK)
+ DrawText("RED", 208, 274, 10, BLACK)
+ DrawText("PINK", 204, 382, 10, BLACK)
+ DrawText("ORANGE", 295, 166, 10, BLACK)
+ DrawText("GOLD", 310, 274, 10, BLACK)
+ DrawText("YELLOW", 300, 382, 10, BLACK)
+ DrawText("DARKGREEN", 382, 166, 10, BLACK)
+ DrawText("LIME", 420, 274, 10, BLACK)
+ DrawText("GREEN", 410, 382, 10, BLACK)
+ DrawText("DARKBLUE", 498, 166, 10, BLACK)
+ DrawText("BLUE", 526, 274, 10, BLACK)
+ DrawText("SKYBLUE", 505, 382, 10, BLACK)
+ DrawText("DARKPURPLE", 592, 166, 10, BLACK)
+ DrawText("VIOLET", 621, 274, 10, BLACK)
+ DrawText("PURPLE", 620, 382, 10, BLACK)
+ DrawText("DARKBROWN", 705, 166, 10, BLACK)
+ DrawText("BROWN", 733, 274, 10, BLACK)
+ DrawText("BEIGE", 737, 382, 10, BLACK)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shapes_logo_raylib.lua b/examples/shapes_logo_raylib.lua
new file mode 100644
index 00000000..4e7f18c4
--- /dev/null
+++ b/examples/shapes_logo_raylib.lua
@@ -0,0 +1,48 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shapes] example - Draw raylib logo using basic shapes
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib logo using shapes")
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawRectangle(screenWidth/2 - 128, screenHeight/2 - 128, 256, 256, BLACK)
+ DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, RAYWHITE)
+ DrawText("raylib", screenWidth/2 - 44, screenHeight/2 + 48, 50, BLACK)
+
+ DrawText("this is NOT a texture!", 350, 370, 10, GRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/shapes_logo_raylib_anim.lua b/examples/shapes_logo_raylib_anim.lua
new file mode 100644
index 00000000..c6c44995
--- /dev/null
+++ b/examples/shapes_logo_raylib_anim.lua
@@ -0,0 +1,127 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [shapes] example - raylib logo animation
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [shapes] example - raylib logo animation")
+
+local logoPositionX = screenWidth/2 - 128
+local logoPositionY = screenHeight/2 - 128
+
+local framesCounter = 0
+local lettersCount = 0
+
+local topSideRecWidth = 16
+local leftSideRecHeight = 16
+
+local bottomSideRecWidth = 16
+local rightSideRecHeight = 16
+
+local state = 0 -- Tracking animation states (State Machine)
+local alpha = 1.0 -- Useful for fading
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (state == 0) then -- State 0: Small box blinking
+ framesCounter = framesCounter + 1
+
+ if (framesCounter == 120) then
+ state = 1
+ framesCounter = 0 -- Reset counter... will be used later...
+ end
+ elseif (state == 1) then -- State 1: Top and left bars growing
+ topSideRecWidth = topSideRecWidth + 4
+ leftSideRecHeight = leftSideRecHeight + 4
+
+ if (topSideRecWidth == 256) then state = 2 end
+ elseif (state == 2) then -- State 2: Bottom and right bars growing
+ bottomSideRecWidth = bottomSideRecWidth + 4
+ rightSideRecHeight = rightSideRecHeight + 4
+
+ if (bottomSideRecWidth == 256) then state = 3 end
+ elseif (state == 3) then -- State 3: Letters appearing (one by one)
+ framesCounter = framesCounter + 1
+
+ if (framesCounter//12 == 1) then -- Every 12 frames, one more letter!
+ lettersCount = lettersCount + 1
+ framesCounter = 0
+ end
+
+ if (lettersCount >= 10) then -- When all letters have appeared, just fade out everything
+ alpha = alpha - 0.02
+
+ if (alpha <= 0.0) then
+ alpha = 0.0
+ state = 4
+ end
+ end
+ elseif (state == 4) then -- State 4: Reset and Replay
+ if (IsKeyPressed(KEY.R)) then
+ framesCounter = 0
+ lettersCount = 0
+
+ topSideRecWidth = 16
+ leftSideRecHeight = 16
+
+ bottomSideRecWidth = 16
+ rightSideRecHeight = 16
+
+ alpha = 1.0
+ state = 0 -- Return to State 0
+ end
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ if (state == 0) then
+ if ((framesCounter//15)%2 == 1) then DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK) end
+ elseif (state == 1) then
+ DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK)
+ DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK)
+ elseif (state == 2) then
+ DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK)
+ DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK)
+
+ DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK)
+ DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK)
+ elseif (state == 3) then
+ DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha))
+ DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha))
+
+ DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha))
+ DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha))
+
+ DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112, 224, 224, Fade(RAYWHITE, alpha))
+
+ DrawText(string.sub("raylib", 0, lettersCount), screenWidth/2 - 44, screenHeight/2 + 48, 50, Fade(BLACK, alpha))
+ elseif (state == 4) then DrawText("[R] REPLAY", 340, 200, 20, GRAY) end
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/text_bmfont_ttf.lua b/examples/text_bmfont_ttf.lua
new file mode 100644
index 00000000..3b8bf004
--- /dev/null
+++ b/examples/text_bmfont_ttf.lua
@@ -0,0 +1,59 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [text] example - BMFont and TTF SpriteFonts loading
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [text] example - bmfont and ttf sprite fonts loading")
+
+local msgBm = "THIS IS AN AngelCode SPRITE FONT"
+local msgTtf = "THIS FONT has been GENERATED from TTF"
+
+-- NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
+local fontBm = LoadSpriteFont("resources/fonts/bmfont.fnt") -- BMFont (AngelCode)
+local fontTtf = LoadSpriteFont("resources/fonts/pixantiqua.ttf") -- TTF font
+
+local fontPosition = Vector2(0, 0)
+fontPosition.x = screenWidth/2 - MeasureTextEx(fontBm, msgBm, fontBm.size, 0).x/2
+fontPosition.y = screenHeight/2 - fontBm.size/2 - 80
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update variables here...
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTextEx(fontBm, msgBm, fontPosition, fontBm.size, 0, MAROON)
+ DrawTextEx(fontTtf, msgTtf, Vector2(60.0, 240.0), fontTtf.size, 2, LIME)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadSpriteFont(fontBm) -- AngelCode SpriteFont unloading
+UnloadSpriteFont(fontTtf) -- TTF SpriteFont unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/text_font_select.lua b/examples/text_font_select.lua
new file mode 100644
index 00000000..f6cea881
--- /dev/null
+++ b/examples/text_font_select.lua
@@ -0,0 +1,143 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [text] example - Font selector
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [text] example - font selector")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+local fonts = {} -- SpriteFont array
+
+fonts[1] = LoadSpriteFont("resources/fonts/alagard.rbmf") -- SpriteFont loading
+fonts[2] = LoadSpriteFont("resources/fonts/pixelplay.rbmf") -- SpriteFont loading
+fonts[3] = LoadSpriteFont("resources/fonts/mecha.rbmf") -- SpriteFont loading
+fonts[4] = LoadSpriteFont("resources/fonts/setback.rbmf") -- SpriteFont loading
+fonts[5] = LoadSpriteFont("resources/fonts/romulus.rbmf") -- SpriteFont loading
+fonts[6] = LoadSpriteFont("resources/fonts/pixantiqua.rbmf") -- SpriteFont loading
+fonts[7] = LoadSpriteFont("resources/fonts/alpha_beta.rbmf") -- SpriteFont loading
+fonts[8] = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf") -- SpriteFont loading
+
+local currentFont = 1 -- Selected font
+
+local colors = { MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, LIME, GOLD, RED }
+
+local fontNames = { "[1] Alagard", "[2] PixelPlay", "[3] MECHA", "[4] Setback",
+ "[5] Romulus", "[6] PixAntiqua", "[7] Alpha Beta", "[8] Jupiter Crash" }
+
+local text = "THIS is THE FONT you SELECTED!" -- Main text
+
+local textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1)
+
+local mousePoint
+
+local btnNextOutColor = DARKBLUE -- Button color (outside line)
+local btnNextInColor = SKYBLUE -- Button color (inside)
+
+local framesCounter = 0 -- Useful to count frames button is 'active' = clicked
+
+local positionY = 180 -- Text selector and button Y position
+
+local btnNextRec = Rectangle(673, positionY, 109, 44) -- Button rectangle (useful for collision)
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+
+ -- Keyboard-based font selection (easy)
+ if (IsKeyPressed(KEY.RIGHT)) then
+ if (currentFont < 8) then currentFont = currentFont + 1 end
+ end
+
+ if (IsKeyPressed(KEY.LEFT)) then
+ if (currentFont > 1) then currentFont = currentFont - 1 end
+ end
+
+ if (IsKeyPressed(KEY.ZERO)) then currentFont = 0
+ elseif (IsKeyPressed(KEY.ONE)) then currentFont = 1
+ elseif (IsKeyPressed(KEY.TWO)) then currentFont = 2
+ elseif (IsKeyPressed(KEY.THREE)) then currentFont = 3
+ elseif (IsKeyPressed(KEY.FOUR)) then currentFont = 4
+ elseif (IsKeyPressed(KEY.FIVE)) then currentFont = 5
+ elseif (IsKeyPressed(KEY.SIX)) then currentFont = 6
+ elseif (IsKeyPressed(KEY.SEVEN)) then currentFont = 7
+ end
+
+ -- Mouse-based font selection (NEXT button logic)
+ mousePoint = GetMousePosition()
+
+ if (CheckCollisionPointRec(mousePoint, btnNextRec)) then
+ -- Mouse hover button logic
+ if (framesCounter == 0) then
+ btnNextOutColor = DARKPURPLE
+ btnNextInColor = PURPLE
+ end
+
+ if (IsMouseButtonDown(MOUSE.LEFT_BUTTON)) then
+ framesCounter = 20 -- Frames button is 'active'
+ btnNextOutColor = MAROON
+ btnNextInColor = RED
+ end
+ else
+ -- Mouse not hover button
+ btnNextOutColor = DARKBLUE
+ btnNextInColor = SKYBLUE
+ end
+
+ if (framesCounter > 0) then framesCounter = framesCounter - 1 end
+
+ if (framesCounter == 1) then -- We change font on frame 1
+ currentFont = currentFont + 1
+ if (currentFont > 7) then currentFont = 0 end
+ end
+
+ -- Text measurement for better positioning on screen
+ textSize = MeasureTextEx(fonts[currentFont], text, fonts[currentFont].size*3, 1)
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("font selector - use arroys, button or numbers", 160, 80, 20, DARKGRAY)
+ DrawLine(120, 120, 680, 120, DARKGRAY)
+
+ DrawRectangle(18, positionY, 644, 44, DARKGRAY)
+ DrawRectangle(20, positionY + 2, 640, 40, LIGHTGRAY)
+ DrawText(fontNames[currentFont], 30, positionY + 13, 20, BLACK)
+ DrawText("< >", 610, positionY + 8, 30, BLACK)
+
+ DrawRectangleRec(btnNextRec, btnNextOutColor)
+ DrawRectangle(675, positionY + 2, 105, 40, btnNextInColor)
+ DrawText("NEXT", 700, positionY + 13, 20, btnNextOutColor)
+
+ DrawTextEx(fonts[currentFont], text, Vector2(screenWidth/2 - textSize.x/2,
+ 260 + (70 - textSize.y)/2), fonts[currentFont].size*3,
+ 1, colors[currentFont])
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+for i = 1, 8 do UnloadSpriteFont(fonts[i]) end -- SpriteFont(s) unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/text_format_text.lua b/examples/text_format_text.lua
new file mode 100644
index 00000000..ba121db3
--- /dev/null
+++ b/examples/text_format_text.lua
@@ -0,0 +1,54 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [text] example - Text formatting
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [text] example - text formatting")
+
+local score = 100020
+local hiscore = 200450
+local lives = 5
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText(string.format("Score: %08i", score), 200, 80, 20, RED)
+
+ DrawText(string.format("HiScore: %08i", hiscore), 200, 120, 20, GREEN)
+
+ DrawText(string.format("Lives: %02i", lives), 200, 160, 40, BLUE)
+
+ DrawText(string.format("Elapsed Time: %02.02f ms", GetFrameTime()*1000), 200, 220, 20, BLACK)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/text_rbmf_fonts.lua b/examples/text_rbmf_fonts.lua
new file mode 100644
index 00000000..31a733f1
--- /dev/null
+++ b/examples/text_rbmf_fonts.lua
@@ -0,0 +1,87 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [text] example - raylib bitmap font (rbmf) loading and usage
+--
+-- NOTE: raylib is distributed with some free to use fonts (even for commercial pourposes!)
+-- To view details and credits for those fonts, check raylib license file
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [text] example - rBMF fonts")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+local fonts = {}
+
+fonts[1] = LoadSpriteFont("resources/fonts/alagard.rbmf") -- rBMF font loading
+fonts[2] = LoadSpriteFont("resources/fonts/pixelplay.rbmf") -- rBMF font loading
+fonts[3] = LoadSpriteFont("resources/fonts/mecha.rbmf") -- rBMF font loading
+fonts[4] = LoadSpriteFont("resources/fonts/setback.rbmf") -- rBMF font loading
+fonts[5] = LoadSpriteFont("resources/fonts/romulus.rbmf") -- rBMF font loading
+fonts[6] = LoadSpriteFont("resources/fonts/pixantiqua.rbmf") -- rBMF font loading
+fonts[7] = LoadSpriteFont("resources/fonts/alpha_beta.rbmf") -- rBMF font loading
+fonts[8] = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf") -- rBMF font loading
+
+local messages = { "ALAGARD FONT designed by Hewett Tsoi",
+ "PIXELPLAY FONT designed by Aleksander Shevchuk",
+ "MECHA FONT designed by Captain Falcon",
+ "SETBACK FONT designed by Brian Kent (AEnigma)",
+ "ROMULUS FONT designed by Hewett Tsoi",
+ "PIXANTIQUA FONT designed by Gerhard Grossmann",
+ "ALPHA_BETA FONT designed by Brian Kent (AEnigma)",
+ "JUPITER_CRASH FONT designed by Brian Kent (AEnigma)" }
+
+local spacings = { 2, 4, 8, 4, 3, 4, 4, 1 }
+
+local positions = {}
+
+for i = 1, 8 do
+ positions[i] = Vector2(0, 0)
+ positions[i].x = screenWidth/2 - MeasureTextEx(fonts[i], messages[i], fonts[i].size*2, spacings[i]).x/2
+ positions[i].y = 60 + fonts[i].size + 45*(i - 1)
+end
+
+local colors = { MAROON, ORANGE, DARKGREEN, DARKBLUE, DARKPURPLE, LIME, GOLD, BLACK }
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("free fonts included with raylib", 250, 20, 20, DARKGRAY)
+ DrawLine(220, 50, 590, 50, DARKGRAY)
+
+ for i = 1, 8 do
+ DrawTextEx(fonts[i], messages[i], positions[i], fonts[i].size*2, spacings[i], colors[i])
+ end
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+for i = 1, 8 do UnloadSpriteFont(fonts[i]) end -- SpriteFont unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/text_sprite_fonts.lua b/examples/text_sprite_fonts.lua
new file mode 100644
index 00000000..341e2ffe
--- /dev/null
+++ b/examples/text_sprite_fonts.lua
@@ -0,0 +1,72 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [text] example - SpriteFont loading and usage
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [text] example - sprite fonts usage")
+
+local msg1 = "THIS IS A custom SPRITE FONT..."
+local msg2 = "...and this is ANOTHER CUSTOM font..."
+local msg3 = "...and a THIRD one! GREAT! :D"
+
+-- NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
+local font1 = LoadSpriteFont("resources/fonts/custom_mecha.png") -- SpriteFont loading
+local font2 = LoadSpriteFont("resources/fonts/custom_alagard.png") -- SpriteFont loading
+local font3 = LoadSpriteFont("resources/fonts/custom_jupiter_crash.png") -- SpriteFont loading
+
+local fontPosition1 = Vector2(0, 0)
+local fontPosition2 = Vector2(0, 0)
+local fontPosition3 = Vector2(0, 0)
+
+fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, font1.size, -3).x/2
+fontPosition1.y = screenHeight/2 - font1.size/2 - 80
+
+fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, font2.size, -2).x/2
+fontPosition2.y = screenHeight/2 - font2.size/2 - 10
+
+fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, font3.size, 2).x/2
+fontPosition3.y = screenHeight/2 - font3.size/2 + 50
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update variables here...
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTextEx(font1, msg1, fontPosition1, font1.size, -3, WHITE)
+ DrawTextEx(font2, msg2, fontPosition2, font2.size, -2, WHITE)
+ DrawTextEx(font3, msg3, fontPosition3, font3.size, 2, WHITE)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadSpriteFont(font1) -- SpriteFont unloading
+UnloadSpriteFont(font2) -- SpriteFont unloading
+UnloadSpriteFont(font3) -- SpriteFont unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/text_writing_anim.lua b/examples/text_writing_anim.lua
new file mode 100644
index 00000000..f4af9f58
--- /dev/null
+++ b/examples/text_writing_anim.lua
@@ -0,0 +1,52 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [text] example - Text Writing Animation
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [text] example - text writing anim")
+
+local message = "This sample illustrates a text writing\nanimation effect! Check it out! )"
+
+local framesCounter = 0
+
+SetTargetFPS(60) -- Set target frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ framesCounter = framesCounter + 1
+
+ if (IsKeyPressed(KEY.ENTER)) then framesCounter = 0 end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText(string.sub(message, 0, framesCounter//10), 210, 160, 20, MAROON)
+
+ DrawText("PRESS [ENTER] to RESTART!", 240, 280, 20, LIGHTGRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_formats_loading.lua b/examples/textures_formats_loading.lua
new file mode 100644
index 00000000..1ce10492
--- /dev/null
+++ b/examples/textures_formats_loading.lua
@@ -0,0 +1,217 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - texture formats loading (compressed and uncompressed)
+--
+-- NOTE: This example requires raylib OpenGL 3.3+ or ES2 versions for compressed textures,
+-- OpenGL 1.1 does not support compressed textures, only uncompressed ones.
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+NUM_TEXTURES = 24
+
+PNG_R8G8B8A8 = 1
+PVR_GRAYSCALE = 2
+PVR_GRAY_ALPHA = 3
+PVR_R5G6B5 = 4
+PVR_R5G5B5A1 = 5
+PVR_R4G4B4A4 = 6
+DDS_R5G6B5 = 7
+DDS_R5G5B5A1 = 8
+DDS_R4G4B4A4 = 9
+DDS_R8G8B8A8 = 10
+DDS_DXT1_RGB = 11
+DDS_DXT1_RGBA = 12
+DDS_DXT3_RGBA = 13
+DDS_DXT5_RGBA = 14
+PKM_ETC1_RGB = 15
+PKM_ETC2_RGB = 16
+PKM_ETC2_EAC_RGBA = 17
+KTX_ETC1_RGB = 18
+KTX_ETC2_RGB = 19
+KTX_ETC2_EAC_RGBA = 20
+ASTC_4x4_LDR = 21
+ASTC_8x8_LDR = 22
+PVR_PVRT_RGB = 23
+PVR_PVRT_RGBA = 24
+
+local formatText = {
+ "PNG_R8G8B8A8",
+ "PVR_GRAYSCALE",
+ "PVR_GRAY_ALPHA",
+ "PVR_R5G6B5",
+ "PVR_R5G5B5A1",
+ "PVR_R4G4B4A4",
+ "DDS_R5G6B5",
+ "DDS_R5G5B5A1",
+ "DDS_R4G4B4A4",
+ "DDS_R8G8B8A8",
+ "DDS_DXT1_RGB",
+ "DDS_DXT1_RGBA",
+ "DDS_DXT3_RGBA",
+ "DDS_DXT5_RGBA",
+ "PKM_ETC1_RGB",
+ "PKM_ETC2_RGB",
+ "PKM_ETC2_EAC_RGBA",
+ "KTX_ETC1_RGB",
+ "KTX_ETC2_RGB",
+ "KTX_ETC2_EAC_RGBA",
+ "ASTC_4x4_LDR",
+ "ASTC_8x8_LDR",
+ "PVR_PVRT_RGB",
+ "PVR_PVRT_RGBA"
+}
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture formats loading")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+
+local sonic = {}
+
+sonic[PNG_R8G8B8A8] = LoadTexture("resources/texture_formats/sonic.png")
+
+-- Load UNCOMPRESSED PVR texture data
+sonic[PVR_GRAYSCALE] = LoadTexture("resources/texture_formats/sonic_GRAYSCALE.pvr")
+sonic[PVR_GRAY_ALPHA] = LoadTexture("resources/texture_formats/sonic_L8A8.pvr")
+sonic[PVR_R5G6B5] = LoadTexture("resources/texture_formats/sonic_R5G6B5.pvr")
+sonic[PVR_R5G5B5A1] = LoadTexture("resources/texture_formats/sonic_R5G5B5A1.pvr")
+sonic[PVR_R4G4B4A4] = LoadTexture("resources/texture_formats/sonic_R4G4B4A4.pvr")
+
+-- Load UNCOMPRESSED DDS texture data
+sonic[DDS_R5G6B5] = LoadTexture("resources/texture_formats/sonic_R5G6B5.dds")
+sonic[DDS_R5G5B5A1] = LoadTexture("resources/texture_formats/sonic_A1R5G5B5.dds")
+sonic[DDS_R4G4B4A4] = LoadTexture("resources/texture_formats/sonic_A4R4G4B4.dds")
+sonic[DDS_R8G8B8A8] = LoadTexture("resources/texture_formats/sonic_A8R8G8B8.dds")
+
+-- Load COMPRESSED DXT DDS texture data (if supported)
+sonic[DDS_DXT1_RGB] = LoadTexture("resources/texture_formats/sonic_DXT1_RGB.dds")
+sonic[DDS_DXT1_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT1_RGBA.dds")
+sonic[DDS_DXT3_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT3_RGBA.dds")
+sonic[DDS_DXT5_RGBA] = LoadTexture("resources/texture_formats/sonic_DXT5_RGBA.dds")
+
+-- Load COMPRESSED ETC texture data (if supported)
+sonic[PKM_ETC1_RGB] = LoadTexture("resources/texture_formats/sonic_ETC1_RGB.pkm")
+sonic[PKM_ETC2_RGB] = LoadTexture("resources/texture_formats/sonic_ETC2_RGB.pkm")
+sonic[PKM_ETC2_EAC_RGBA] = LoadTexture("resources/texture_formats/sonic_ETC2_EAC_RGBA.pkm")
+
+sonic[KTX_ETC1_RGB] = LoadTexture("resources/texture_formats/sonic_ETC1_RGB.ktx")
+sonic[KTX_ETC2_RGB] = LoadTexture("resources/texture_formats/sonic_ETC2_RGB.ktx")
+sonic[KTX_ETC2_EAC_RGBA] = LoadTexture("resources/texture_formats/sonic_ETC2_EAC_RGBA.ktx")
+
+-- Load COMPRESSED ASTC texture data (if supported)
+sonic[ASTC_4x4_LDR] = LoadTexture("resources/texture_formats/sonic_ASTC_4x4_ldr.astc")
+sonic[ASTC_8x8_LDR] = LoadTexture("resources/texture_formats/sonic_ASTC_8x8_ldr.astc")
+
+-- Load COMPRESSED PVR texture data (if supported)
+sonic[PVR_PVRT_RGB] = LoadTexture("resources/texture_formats/sonic_PVRT_RGB.pvr")
+sonic[PVR_PVRT_RGBA] = LoadTexture("resources/texture_formats/sonic_PVRT_RGBA.pvr")
+
+local selectedFormat = PNG_R8G8B8A8
+
+local selectRecs = {}
+
+for i = 1, NUM_TEXTURES do
+ if ((i - 1) < NUM_TEXTURES//2) then selectRecs[i] = Rectangle(40, 30 + 32*(i - 1), 150, 30)
+ else selectRecs[i] = Rectangle(40 + 152, 30 + 32*((i - 1) - NUM_TEXTURES//2), 150, 30) end
+end
+
+-- Texture sizes in KB
+local textureSizes = {
+ 512*512*32/8/1024, --PNG_R8G8B8A8 (32 bpp)
+ 512*512*8/8/1024, --PVR_GRAYSCALE (8 bpp)
+ 512*512*16/8/1024, --PVR_GRAY_ALPHA (16 bpp)
+ 512*512*16/8/1024, --PVR_R5G6B5 (16 bpp)
+ 512*512*16/8/1024, --PVR_R5G5B5A1 (16 bpp)
+ 512*512*16/8/1024, --PVR_R4G4B4A4 (16 bpp)
+ 512*512*16/8/1024, --DDS_R5G6B5 (16 bpp)
+ 512*512*16/8/1024, --DDS_R5G5B5A1 (16 bpp)
+ 512*512*16/8/1024, --DDS_R4G4B4A4 (16 bpp)
+ 512*512*32/8/1024, --DDS_R8G8B8A8 (32 bpp)
+ 512*512*4/8/1024, --DDS_DXT1_RGB (4 bpp) -Compressed-
+ 512*512*4/8/1024, --DDS_DXT1_RGBA (4 bpp) -Compressed-
+ 512*512*8/8/1024, --DDS_DXT3_RGBA (8 bpp) -Compressed-
+ 512*512*8/8/1024, --DDS_DXT5_RGBA (8 bpp) -Compressed-
+ 512*512*4/8/1024, --PKM_ETC1_RGB (4 bpp) -Compressed-
+ 512*512*4/8/1024, --PKM_ETC2_RGB (4 bpp) -Compressed-
+ 512*512*8/8/1024, --PKM_ETC2_EAC_RGBA (8 bpp) -Compressed-
+ 512*512*4/8/1024, --KTX_ETC1_RGB (4 bpp) -Compressed-
+ 512*512*4/8/1024, --KTX_ETC2_RGB (4 bpp) -Compressed-
+ 512*512*8/8/1024, --KTX_ETC2_EAC_RGBA (8 bpp) -Compressed-
+ 512*512*8/8/1024, --ASTC_4x4_LDR (8 bpp) -Compressed-
+ 512*512*2/8/1024, --ASTC_8x8_LDR (2 bpp) -Compressed-
+ 512*512*4/8/1024, --PVR_PVRT_RGB (4 bpp) -Compressed-
+ 512*512*4/8/1024, --PVR_PVRT_RGBA (4 bpp) -Compressed-
+}
+
+SetTargetFPS(60) -- Set our game to run at 60 frames-per-second
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsKeyPressed(KEY.DOWN)) then
+ selectedFormat = selectedFormat + 1
+ if (selectedFormat > NUM_TEXTURES) then selectedFormat = 1 end
+ elseif (IsKeyPressed(KEY.UP)) then
+ selectedFormat = selectedFormat - 1
+ if (selectedFormat < 1) then selectedFormat = NUM_TEXTURES end
+ elseif (IsKeyPressed(KEY.RIGHT)) then
+ if (selectedFormat < NUM_TEXTURES//2) then selectedFormat = selectedFormat + NUM_TEXTURES//2 end
+ elseif (IsKeyPressed(KEY.LEFT)) then
+ if (selectedFormat > NUM_TEXTURES//2) then selectedFormat = selectedFormat - NUM_TEXTURES//2 end
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ -- Draw rectangles
+ for i = 1, NUM_TEXTURES do
+ if (i == selectedFormat) then
+ DrawRectangleRec(selectRecs[i], SKYBLUE)
+ DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, BLUE)
+ DrawText(formatText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(formatText[i], 10)//2, selectRecs[i].y + 11, 10, DARKBLUE)
+ else
+ DrawRectangleRec(selectRecs[i], LIGHTGRAY)
+ DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, GRAY)
+ DrawText(formatText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(formatText[i], 10)//2, selectRecs[i].y + 11, 10, DARKGRAY)
+ end
+ end
+
+ -- Draw selected texture
+ if (sonic[selectedFormat].id ~= 0) then DrawTexture(sonic[selectedFormat], 350, -10, WHITE)
+ else
+ DrawRectangleLines(488, 165, 200, 110, DARKGRAY)
+ DrawText("FORMAT", 550, 180, 20, MAROON)
+ DrawText("NOT SUPPORTED", 500, 210, 20, MAROON)
+ DrawText("ON YOUR GPU", 520, 240, 20, MAROON)
+ end
+
+ DrawText("Select texture format (use cursor keys):", 40, 10, 10, DARKGRAY)
+ DrawText("Required GPU memory size (VRAM):", 40, 427, 10, DARKGRAY)
+ DrawText(string.format("%4.0f KB", textureSizes[selectedFormat]), 240, 420, 20, DARKBLUE)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+for i = 1, NUM_TEXTURES do UnloadTexture(sonic[i]) end
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_image_drawing.lua b/examples/textures_image_drawing.lua
new file mode 100644
index 00000000..0261b243
--- /dev/null
+++ b/examples/textures_image_drawing.lua
@@ -0,0 +1,70 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Image loading and drawing on it
+--
+-- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - image drawing")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+
+local cat = LoadImage("resources/cat.png") -- Load image in CPU memory (RAM)
+cat = ImageCrop(cat, Rectangle(100, 10, 280, 380)) -- Crop an image piece
+cat = ImageFlipHorizontal(cat) -- Flip cropped image horizontally
+cat = ImageResize(cat, 150, 200) -- Resize flipped-cropped image
+
+local parrots = LoadImage("resources/parrots.png") -- Load image in CPU memory (RAM)
+
+-- Draw one image over the other with a scaling of 1.5f
+parrots = ImageDraw(parrots, cat, Rectangle(0, 0, cat.width, cat.height), Rectangle(30, 40, cat.width*1.5, cat.height*1.5))
+parrots = ImageCrop(parrots, Rectangle(0, 50, parrots.width, parrots.height - 100)) -- Crop resulting image
+
+UnloadImage(cat) -- Unload image from RAM
+
+local 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
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 40, WHITE)
+ DrawRectangleLines(screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2 - 40, texture.width, texture.height, DARKGRAY)
+
+ DrawText("We are drawing only one texture from various images composed!", 240, 350, 10, DARKGRAY)
+ DrawText("Source images have been cropped, scaled, flipped and copied one over the other.", 190, 370, 10, DARKGRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(texture) -- Texture unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_image_loading.lua b/examples/textures_image_loading.lua
new file mode 100644
index 00000000..05dbce7f
--- /dev/null
+++ b/examples/textures_image_loading.lua
@@ -0,0 +1,55 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Image loading and texture creation
+--
+-- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - image loading")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+
+local image = LoadImage("resources/raylib_logo.png") -- Loaded in CPU memory (RAM)
+local texture = LoadTextureFromImage(image) -- Image converted to texture, GPU memory (VRAM)
+
+UnloadImage(image) -- Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE)
+
+ DrawText("this IS a texture loaded from an image!", 300, 370, 10, GRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(texture) -- Texture unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_image_processing.lua b/examples/textures_image_processing.lua
new file mode 100644
index 00000000..b7304b37
--- /dev/null
+++ b/examples/textures_image_processing.lua
@@ -0,0 +1,134 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Image processing
+--
+-- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+--#include <stdlib.h> -- Required for: free()
+
+NUM_PROCESSES = 8
+
+-- enum ImageProcess
+local COLOR_NONE = 1
+local COLOR_GRAYSCALE = 2
+local COLOR_TINT = 3
+local COLOR_INVERT = 4
+local COLOR_CONTRAST = 5
+local COLOR_BRIGHTNESS = 6
+local FLIP_VERTICAL = 7
+local FLIP_HORIZONTAL = 8
+
+local processText = {
+ "NO PROCESSING",
+ "COLOR GRAYSCALE",
+ "COLOR TINT",
+ "COLOR INVERT",
+ "COLOR CONTRAST",
+ "COLOR BRIGHTNESS",
+ "FLIP VERTICAL",
+ "FLIP HORIZONTAL"
+}
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - image processing")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+
+local image = LoadImage("resources/parrots.png") -- Loaded in CPU memory (RAM)
+image = ImageFormat(image, TextureFormat.UNCOMPRESSED_R8G8B8A8) -- Format image to RGBA 32bit (required for texture update)
+local texture = LoadTextureFromImage(image) -- Image converted to texture, GPU memory (VRAM)
+
+local currentProcess = COLOR_NONE
+local textureReload = false
+
+local selectRecs = {}
+
+for i = 1, NUM_PROCESSES do selectRecs[i] = Rectangle(40, 50 + 32*i, 150, 30) end
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsKeyPressed(KEY.DOWN)) then
+ currentProcess = currentProcess + 1
+ if (currentProcess > NUM_PROCESSES) then currentProcess = 1 end
+ textureReload = true
+ elseif (IsKeyPressed(KEY.UP)) then
+ currentProcess = currentProcess - 1
+ if (currentProcess < 1) then currentProcess = NUM_PROCESSES end
+ textureReload = true
+ end
+
+ if (textureReload) then
+ UnloadImage(image) -- Unload current image data
+ image = LoadImage("resources/parrots.png") -- Re-load image data
+
+ -- NOTE: Image processing is a costly CPU process to be done every frame,
+ -- If image processing is required in a frame-basis, it should be done
+ -- with a texture and by shaders
+ if (currentProcess == COLOR_GRAYSCALE) then image = ImageColorGrayscale(image)
+ elseif (currentProcess == COLOR_TINT) then image = ImageColorTint(image, GREEN)
+ elseif (currentProcess == COLOR_INVERT) then image = ImageColorInvert(image)
+ elseif (currentProcess == COLOR_CONTRAST) then image = ImageColorContrast(image, -40)
+ elseif (currentProcess == COLOR_BRIGHTNESS) then image = ImageColorBrightness(image, -80)
+ elseif (currentProcess == FLIP_VERTICAL) then image = ImageFlipVertical(image)
+ elseif (currentProcess == FLIP_HORIZONTAL) then image = ImageFlipHorizontal(image)
+ end
+
+ local pixels = {}
+ pixels = GetImageData(image) -- Get pixel data from image (RGBA 32bit)
+ texture = UpdateTexture(texture, pixels) -- Update texture with new image data
+
+ textureReload = false
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawText("IMAGE PROCESSING:", 40, 30, 10, DARKGRAY)
+
+ -- Draw rectangles
+ for i = 1, NUM_PROCESSES do
+ if (i == currentProcess) then
+ DrawRectangleRec(selectRecs[i], SKYBLUE)
+ DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, BLUE)
+ DrawText(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)//2, selectRecs[i].y + 11, 10, DARKBLUE)
+ else
+ DrawRectangleRec(selectRecs[i], LIGHTGRAY)
+ DrawRectangleLines(selectRecs[i].x, selectRecs[i].y, selectRecs[i].width, selectRecs[i].height, GRAY)
+ DrawText(processText[i], selectRecs[i].x + selectRecs[i].width/2 - MeasureText(processText[i], 10)//2, selectRecs[i].y + 11, 10, DARKGRAY)
+ end
+ end
+
+ DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE)
+ DrawRectangleLines(screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, texture.width, texture.height, BLACK)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(texture) -- Unload texture from VRAM
+UnloadImage(image) -- Unload image from RAM
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_logo_raylib.lua b/examples/textures_logo_raylib.lua
new file mode 100644
index 00000000..3abcd802
--- /dev/null
+++ b/examples/textures_logo_raylib.lua
@@ -0,0 +1,49 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Texture loading and drawing
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture loading and drawing")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+local texture = LoadTexture("resources/raylib_logo.png") -- Texture loading
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE)
+
+ DrawText("this IS a texture!", 360, 370, 10, GRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(texture) -- Texture unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_particles_trail_blending.lua b/examples/textures_particles_trail_blending.lua
new file mode 100644
index 00000000..d2c2518e
--- /dev/null
+++ b/examples/textures_particles_trail_blending.lua
@@ -0,0 +1,113 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib example - particles trail blending
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+MAX_PARTICLES = 200
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - particles trail blending")
+
+-- Particles pool, reuse them!
+local mouseTail = {}
+
+-- Initialize particles
+for i = 1, MAX_PARTICLES do
+ mouseTail[i] = {}
+ mouseTail[i].position = Vector2(0, 0)
+ mouseTail[i].color = Color(GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255)
+ mouseTail[i].alpha = 1.0
+ mouseTail[i].size = GetRandomValue(1, 30)/20.0
+ mouseTail[i].rotation = GetRandomValue(0, 360)
+ mouseTail[i].active = false
+end
+
+local gravity = 3.0
+
+local smoke = LoadTexture("resources/smoke.png")
+
+local blending = BlendMode.ALPHA
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+
+ -- Activate one particle every frame and Update active particles
+ -- NOTE: Particles initial position should be mouse position when activated
+ -- NOTE: Particles fall down with gravity and rotation... and disappear after 2 seconds (alpha = 0)
+ -- NOTE: When a particle disappears, active = false and it can be reused.
+ for i = 1, MAX_PARTICLES do
+ if (not mouseTail[i].active) then
+ mouseTail[i].active = true
+ mouseTail[i].alpha = 1.0
+ mouseTail[i].position = GetMousePosition()
+ break
+ end
+ end
+
+ for i = 1, MAX_PARTICLES do
+ if (mouseTail[i].active) then
+ mouseTail[i].position.y = mouseTail[i].position.y + gravity
+ mouseTail[i].alpha = mouseTail[i].alpha - 0.01
+
+ if (mouseTail[i].alpha <= 0.0) then mouseTail[i].active = false end
+
+ mouseTail[i].rotation = mouseTail[i].rotation + 5.0
+ end
+ end
+
+ if (IsKeyPressed(KEY.SPACE)) then
+ if (blending == BlendMode.ALPHA) then blending = BlendMode.ADDITIVE
+ else blending = BlendMode.ALPHA end
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(DARKGRAY)
+
+ BeginBlendMode(blending)
+
+ -- Draw active particles
+ for i = 1, MAX_PARTICLES do
+ if (mouseTail[i].active) then
+ DrawTexturePro(smoke, Rectangle(0, 0, smoke.width, smoke.height),
+ Rectangle(mouseTail[i].position.x, mouseTail[i].position.y,
+ smoke.width*mouseTail[i].size//1, smoke.height*mouseTail[i].size//1),
+ Vector2(smoke.width*mouseTail[i].size/2, smoke.height*mouseTail[i].size/2),
+ mouseTail[i].rotation, Fade(mouseTail[i].color, mouseTail[i].alpha)) end
+ end
+
+ EndBlendMode()
+
+ DrawText("PRESS SPACE to CHANGE BLENDING MODE", 180, 20, 20, BLACK)
+
+ if (blending == BlendMode.ALPHA) then DrawText("ALPHA BLENDING", 290, screenHeight - 40, 20, BLACK)
+ else DrawText("ADDITIVE BLENDING", 280, screenHeight - 40, 20, RAYWHITE) end
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(smoke)
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_raw_data.lua b/examples/textures_raw_data.lua
new file mode 100644
index 00000000..0bad1771
--- /dev/null
+++ b/examples/textures_raw_data.lua
@@ -0,0 +1,83 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Load textures from raw data
+--
+-- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+--#include <stdlib.h> -- Required for malloc() and free()
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture from raw data")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+
+-- Load RAW image data (512x512, 32bit RGBA, no file header)
+local sonicRaw = LoadImageRaw("resources/texture_formats/sonic_R8G8B8A8.raw", 512, 512, TextureFormat.UNCOMPRESSED_R8G8B8A8, 0)
+local sonic = LoadTextureFromImage(sonicRaw) -- Upload CPU (RAM) image to GPU (VRAM)
+UnloadImage(sonicRaw) -- Unload CPU (RAM) image data
+
+-- Generate a checked texture by code (1024x1024 pixels)
+local width = 1024
+local height = 1024
+
+-- Dynamic memory allocation to store pixels data (Color type)
+local pixels = {}
+
+for y = 1, height do
+ for x = 1, width do
+ if ((((x - 1)/32+(y - 1)//32)//1)%2 == 0) then pixels[(y - 1)*height + x] = DARKBLUE
+ else pixels[(y - 1)*height + x] = SKYBLUE end
+ end
+end
+
+-- Load pixels data into an image structure and create texture
+local checkedIm = LoadImageEx(pixels, width, height)
+local checked = LoadTextureFromImage(checkedIm)
+UnloadImage(checkedIm) -- Unload CPU (RAM) image data
+
+-- Dynamic memory must be freed after using it
+--free(pixels) -- Unload CPU (RAM) pixels data
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTexture(checked, screenWidth/2 - checked.width/2, screenHeight/2 - checked.height/2, Fade(WHITE, 0.3))
+ DrawTexture(sonic, 330, -20, WHITE)
+
+ DrawText("CHECKED TEXTURE ", 84, 100, 30, DARKBLUE)
+ DrawText("GENERATED by CODE", 72, 164, 30, DARKBLUE)
+ DrawText("and RAW IMAGE LOADING", 46, 226, 30, DARKBLUE)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(sonic) -- Texture unloading
+UnloadTexture(checked) -- Texture unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_rectangle.lua b/examples/textures_rectangle.lua
new file mode 100644
index 00000000..5f481679
--- /dev/null
+++ b/examples/textures_rectangle.lua
@@ -0,0 +1,69 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Texture loading and drawing a part defined by a rectangle
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [texture] example - texture rectangle")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+local guybrush = LoadTexture("resources/guybrush.png") -- Texture loading
+
+local position = Vector2(350.0, 240.0)
+local frameRec = Rectangle(0, 0, guybrush.width/7, guybrush.height)
+local currentFrame = 0
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ if (IsKeyPressed(KEY.RIGHT)) then
+ currentFrame = currentFrame + 1
+
+ if (currentFrame > 6) then currentFrame = 0 end
+
+ frameRec.x = currentFrame*guybrush.width/7
+ end
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTexture(guybrush, 35, 40, WHITE)
+ DrawRectangleLines(35, 40, guybrush.width, guybrush.height, LIME)
+
+ DrawTextureRec(guybrush, frameRec, position, WHITE) -- Draw part of the texture
+
+ DrawRectangleLines(35 + frameRec.x, 40 + frameRec.y, frameRec.width, frameRec.height, RED)
+
+ DrawText("PRESS RIGHT KEY to", 540, 310, 10, GRAY)
+ DrawText("CHANGE DRAWING RECTANGLE", 520, 330, 10, GRAY)
+
+ DrawText("Guybrush Ulysses Threepwood,", 100, 300, 10, GRAY)
+ DrawText("main character of the Monkey Island series", 80, 320, 10, GRAY)
+ DrawText("of computer adventure games by LucasArts.", 80, 340, 10, GRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(guybrush) -- Texture unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_srcrec_dstrec.lua b/examples/textures_srcrec_dstrec.lua
new file mode 100644
index 00000000..f94deb3e
--- /dev/null
+++ b/examples/textures_srcrec_dstrec.lua
@@ -0,0 +1,71 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Texture source and destination rectangles
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] examples - texture source and destination rectangles")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+local guybrush = LoadTexture("resources/guybrush.png") -- Texture loading
+
+local frameWidth = guybrush.width/7
+local frameHeight = guybrush.height
+
+-- NOTE: Source rectangle (part of the texture to use for drawing)
+local sourceRec = Rectangle(0, 0, frameWidth, frameHeight)
+
+-- NOTE: Destination rectangle (screen rectangle where drawing part of texture)
+local destRec = Rectangle(screenWidth/2, screenHeight/2, frameWidth*2, frameHeight*2)
+
+-- NOTE: Origin of the texture (rotation/scale point), it's relative to destination rectangle size
+local origin = Vector2(frameWidth, frameHeight)
+
+local rotation = 0
+
+SetTargetFPS(60)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ rotation = rotation + 1
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ -- NOTE: Using DrawTexturePro() we can easily rotate and scale the part of the texture we draw
+ -- sourceRec defines the part of the texture we use for drawing
+ -- destRec defines the rectangle where our texture part will fit (scaling it to fit)
+ -- origin defines the point of the texture used as reference for rotation and scaling
+ -- rotation defines the texture rotation (using origin as rotation point)
+ DrawTexturePro(guybrush, sourceRec, destRec, origin, rotation, WHITE)
+
+ DrawLine(destRec.x, 0, destRec.x, screenHeight, GRAY)
+ DrawLine(0, destRec.y, screenWidth, destRec.y, GRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(guybrush) -- Texture unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/examples/textures_to_image.lua b/examples/textures_to_image.lua
new file mode 100644
index 00000000..b7a2d4ed
--- /dev/null
+++ b/examples/textures_to_image.lua
@@ -0,0 +1,60 @@
+-------------------------------------------------------------------------------------------
+--
+-- raylib [textures] example - Retrieve image data from texture: GetTextureData()
+--
+-- NOTE: Images are loaded in CPU memory (RAM) textures are loaded in GPU memory (VRAM)
+--
+-- This example has been created using raylib 1.6 (www.raylib.com)
+-- raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+--
+-- Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+--
+-------------------------------------------------------------------------------------------
+
+-- Initialization
+-------------------------------------------------------------------------------------------
+local screenWidth = 800
+local screenHeight = 450
+
+InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture to image")
+
+-- NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
+
+local image = LoadImage("resources/raylib_logo.png") -- Load image data into CPU memory (RAM)
+local texture = LoadTextureFromImage(image) -- Image converted to texture, GPU memory (RAM -> VRAM)
+UnloadImage(image) -- Unload image data from CPU memory (RAM)
+
+image = GetTextureData(texture) -- Retrieve image data from GPU memory (VRAM -> RAM)
+UnloadTexture(texture) -- Unload texture from GPU memory (VRAM)
+
+texture = LoadTextureFromImage(image) -- Recreate texture from retrieved image data (RAM -> VRAM)
+UnloadImage(image) -- Unload retrieved image data from CPU memory (RAM)
+-------------------------------------------------------------------------------------------
+
+-- Main game loop
+while not WindowShouldClose() do -- Detect window close button or ESC key
+ -- Update
+ ---------------------------------------------------------------------------------------
+ -- TODO: Update your variables here
+ ---------------------------------------------------------------------------------------
+
+ -- Draw
+ ---------------------------------------------------------------------------------------
+ BeginDrawing()
+
+ ClearBackground(RAYWHITE)
+
+ DrawTexture(texture, screenWidth/2 - texture.width/2, screenHeight/2 - texture.height/2, WHITE)
+
+ DrawText("this IS a texture loaded from an image!", 300, 370, 10, GRAY)
+
+ EndDrawing()
+ ---------------------------------------------------------------------------------------
+end
+
+-- De-Initialization
+-------------------------------------------------------------------------------------------
+UnloadTexture(texture) -- Texture unloading
+
+CloseWindow() -- Close window and OpenGL context
+------------------------------------------------------------------------------------------- \ No newline at end of file
diff --git a/games/arkanoid.lua b/games/arkanoid.lua
new file mode 100644
index 00000000..2dc59247
--- /dev/null
+++ b/games/arkanoid.lua
@@ -0,0 +1,297 @@
+--[[
+
+ raylib - sample game: arkanoid
+
+ Sample game Marc Palau and Ramon Santamaria
+
+ This game has been created using raylib v1.3 (www.raylib.com)
+ raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+
+ Copyright (c) 2015 Ramon Santamaria (@raysan5)
+
+ Translated to Lua by Ghassan Al-Mashareqa ([email protected])
+
+--]]
+
+------------------------------------------------------------------------------------
+-- Some Defines
+------------------------------------------------------------------------------------
+PLAYER_MAX_LIFE = 5
+LINES_OF_BRICKS = 5
+BRICKS_PER_LINE = 20
+
+------------------------------------------------------------------------------------
+-- Types and Structures Definition
+------------------------------------------------------------------------------------
+
+GameScreen = { LOGO = 0, TITLE = 1, GAMEPLAY = 2, ENDING = 3 }
+
+function Player()
+ return { position = Vector2(0,0), size = Vector2(0,0), life = 0 }
+end
+
+function Ball()
+ return { position = Vector2(0,0), speed = Vector2(0,0), radius = 0, active = false }
+end
+
+function Brick()
+ return { position = Vector2(0,0), active = false }
+end
+
+--------------------------------------------------------------------------------------
+-- Global Variables Declaration
+--------------------------------------------------------------------------------------
+screenWidth = 800;
+screenHeight = 450;
+
+framesCounter = 0;
+gameOver = false;
+pause = false;
+
+player = Player()
+ball = Ball()
+brick = {}--[LINES_OF_BRICKS][BRICKS_PER_LINE];
+for i = 0, LINES_OF_BRICKS-1 do
+ brick[i] = {}
+ for j = 0, BRICKS_PER_LINE-1 do
+ brick[i][j] = Brick()
+ end
+end
+brickSize = Vector2(0,0)
+
+
+--------------------------------------------------------------------------------------
+-- Module Functions Definitions (local)
+--------------------------------------------------------------------------------------
+
+-- Initialize game variables
+function InitGame()
+
+ brickSize = Vector2(GetScreenWidth()/BRICKS_PER_LINE, 40)
+
+ -- Initialize player
+ player.position = Vector2(screenWidth/2, screenHeight*7/8)
+ player.size = Vector2(screenWidth/10, 20)
+ player.life = PLAYER_MAX_LIFE;
+
+ -- Initialize ball
+ ball.position = Vector2(screenWidth/2, screenHeight*7/8 - 30)
+ ball.speed = Vector2(0, 0)
+ ball.radius = 7;
+ ball.active = false;
+
+ -- Initialize bricks
+ local initialDownPosition = 50;
+
+ for i = 0, LINES_OF_BRICKS-1 do
+ for j = 0, BRICKS_PER_LINE-1 do
+ brick[i][j].position = Vector2(j*brickSize.x + brickSize.x/2, i*brickSize.y + initialDownPosition)
+ brick[i][j].active = true;
+ end
+ end
+end
+
+-- Update game (one frame)
+function UpdateGame()
+
+ if (not gameOver) then
+ if (IsKeyPressed(KEY.P)) then pause = not pause; end
+
+ if (not pause) then
+ -- Player movement
+ if (IsKeyDown(KEY.LEFT)) then player.position.x = player.position.x - 5; end
+ if ((player.position.x - player.size.x/2) <= 0) then player.position.x = player.size.x/2; end
+ if (IsKeyDown(KEY.RIGHT)) then player.position.x = player.position.x + 5; end
+ if ((player.position.x + player.size.x/2) >= screenWidth) then player.position.x = screenWidth - player.size.x/2; end
+
+ -- Launch ball
+ if (not ball.active) then
+ if (IsKeyPressed(KEY.SPACE)) then
+ ball.active = true;
+ ball.speed = Vector2(0, -5)
+ end
+ end
+
+ UpdateBall();
+
+ -- Game over logic
+ if (player.life <= 0) then
+ gameOver = true;
+ else
+ gameOver = true;
+
+ for i = 0, LINES_OF_BRICKS-1 do
+ for j = 0, BRICKS_PER_LINE-1 do
+ if (brick[i][j].active) then gameOver = false; end
+ end
+ end
+ end
+ end
+ else
+ if (IsKeyPressed(KEY.ENTER)) then
+ InitGame();
+ gameOver = false;
+ end
+ end
+
+end
+
+-- Draw game (one frame)
+function DrawGame()
+
+ BeginDrawing();
+
+ ClearBackground(RAYWHITE);
+
+ if (not gameOver) then
+ -- Draw player bar
+ DrawRectangle(player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y, BLACK);
+
+ -- Draw player lives
+ for i = 0, player.life-1 do
+ DrawRectangle(20 + 40*i, screenHeight - 30, 35, 10, LIGHTGRAY);
+ end
+
+ -- Draw ball
+ DrawCircleV(ball.position, ball.radius, MAROON);
+
+ -- Draw bricks
+ for i = 0, LINES_OF_BRICKS-1 do
+ for j = 0, BRICKS_PER_LINE-1 do
+ if (brick[i][j].active) then
+ if ((i + j) % 2 == 0) then
+ DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, GRAY);
+ else
+ DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, DARKGRAY);
+ end
+ end
+ end
+ end
+
+ if (pause) then
+ DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
+ end
+ else
+ DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
+ end
+
+ EndDrawing();
+end
+
+-- Unload game variables
+function UnloadGame()
+ -- TODO: Unload all dynamic loaded data (textures, sounds, models...)
+end
+
+-- Update and Draw (one frame)
+function UpdateDrawFrame()
+ UpdateGame();
+ DrawGame();
+end
+
+----------------------------------------------------------------------------------------
+-- Additional module functions
+----------------------------------------------------------------------------------------
+function UpdateBall()
+ -- Update position
+ if (ball.active) then
+ ball.position.x = ball.position.x + ball.speed.x;
+ ball.position.y = ball.position.y + ball.speed.y;
+ else
+ ball.position = Vector2(player.position.x, screenHeight*7/8 - 30);
+ end
+
+ -- Bounce in x
+ if (((ball.position.x + ball.radius) >= screenWidth) or ((ball.position.x - ball.radius) <= 0))
+ then
+ ball.speed.x = ball.speed.x * -1;
+ end
+
+ -- Bounce in y
+ if ((ball.position.y - ball.radius) <= 0) then
+ ball.speed.y = ball.speed.y * -1;
+ end
+
+ -- Ball reaches bottom of the screen
+ if ((ball.position.y + ball.radius) >= screenHeight) then
+ ball.speed = Vector2(0, 0);
+ ball.active = false;
+
+ player.life = player.life - 1;
+ end
+
+ -- Collision logic: ball vs player
+ if CheckCollisionCircleRec(ball.position, ball.radius,
+ Rectangle(
+ player.position.x - player.size.x/2,
+ player.position.y - player.size.y/2,
+ player.size.x,
+ player.size.y)) then
+ if (ball.speed.y > 0) then
+ ball.speed.y = ball.speed.y * -1;
+ ball.speed.x = (ball.position.x - player.position.x)/(player.size.x/2)*5;
+ end
+ end
+
+ -- Collision logic: ball vs bricks
+ for i = 0,LINES_OF_BRICKS-1 do
+ for j = 0,BRICKS_PER_LINE-1 do
+ if (brick[i][j].active) then
+ -- Hit below
+ if (((ball.position.y - ball.radius) <= (brick[i][j].position.y + brickSize.y/2)) and
+ ((ball.position.y - ball.radius) > (brick[i][j].position.y + brickSize.y/2 + ball.speed.y)) and
+ ((math.abs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) and (ball.speed.y < 0))
+ then
+ brick[i][j].active = false;
+ ball.speed.y = ball.speed.y * -1;
+ -- Hit above
+ elseif (((ball.position.y + ball.radius) >= (brick[i][j].position.y - brickSize.y/2)) and
+ ((ball.position.y + ball.radius) < (brick[i][j].position.y - brickSize.y/2 + ball.speed.y)) and
+ ((math.abs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) and (ball.speed.y > 0))
+ then
+ brick[i][j].active = false;
+ ball.speed.y = ball.speed.y * -1;
+ -- Hit left
+ elseif (((ball.position.x + ball.radius) >= (brick[i][j].position.x - brickSize.x/2)) and
+ ((ball.position.x + ball.radius) < (brick[i][j].position.x - brickSize.x/2 + ball.speed.x)) and
+ ((math.abs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) and (ball.speed.x > 0))
+ then
+ brick[i][j].active = false;
+ ball.speed.x = ball.speed.x * -1;
+ -- Hit right
+ elseif (((ball.position.x - ball.radius) <= (brick[i][j].position.x + brickSize.x/2)) and
+ ((ball.position.x - ball.radius) > (brick[i][j].position.x + brickSize.x/2 + ball.speed.x)) and
+ ((math.abs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) and (ball.speed.x < 0))
+ then
+ brick[i][j].active = false;
+ ball.speed.x = ball.speed.x * -1;
+ end
+ end
+ end
+ end
+end
+
+InitWindow(screenWidth, screenHeight, "sample game: arkanoid");
+
+InitGame();
+
+SetTargetFPS(60);
+----------------------------------------------------------------------------------------
+
+-- Main game loop
+while (not WindowShouldClose()) -- Detect window close button or ESC key
+do
+ -- Update
+ ------------------------------------------------------------------------------------
+ UpdateGame();
+ ------------------------------------------------------------------------------------
+
+ -- Draw
+ ------------------------------------------------------------------------------------
+ DrawGame();
+ ------------------------------------------------------------------------------------
+end
+
+UnloadGame(); -- Unload loaded data (textures, sounds, models...)
+
+CloseWindow(); -- Close window and OpenGL context
diff --git a/games/drturtle/05_drturtle_audio.c b/games/drturtle/05_drturtle_audio.c
index 4a36d015..b94de106 100644
--- a/games/drturtle/05_drturtle_audio.c
+++ b/games/drturtle/05_drturtle_audio.c
@@ -12,7 +12,7 @@
*
* Enjoy using raylib. :)
*
-* This game has been created using raylib 1.1 (www.raylib.com)
+* This game has been created using raylib 1.6 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - [email protected])
@@ -59,8 +59,9 @@ int main()
Sound die = LoadSound("resources/die.wav");
Sound growl = LoadSound("resources/gamera.wav");
- // Start playing streaming music
- PlayMusicStream("resources/speeding.ogg");
+ // Load music stream and start playing music
+ Music music = LoadMusicStream("resources/speeding.ogg");
+ PlayMusicStream(music);
// Define scrolling variables
int backScrolling = 0;
@@ -118,6 +119,8 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
+ UpdateMusicStream(music); // Refill music stream buffers (if required)
+
framesCounter++;
// Game screens management
@@ -458,10 +461,10 @@ int main()
UnloadSound(die);
UnloadSound(growl);
- StopMusicStream(); // Stop music
- CloseAudioDevice(); // Close audio device
+ UnloadMusicStream(music); // Unload music
+ CloseAudioDevice(); // Close audio device
- CloseWindow(); // Close window and OpenGL context
+ CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
diff --git a/games/drturtle/06_drturtle_final.c b/games/drturtle/06_drturtle_final.c
index 128b23a5..48708094 100644
--- a/games/drturtle/06_drturtle_final.c
+++ b/games/drturtle/06_drturtle_final.c
@@ -12,7 +12,7 @@
*
* Enjoy using raylib. :)
*
-* This game has been created using raylib 1.1 (www.raylib.com)
+* This game has been created using raylib 1.6 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - [email protected])
@@ -39,7 +39,7 @@ int main()
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Initialize audio device
- InitAudioDevice();
+ InitAudioDevice();
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
@@ -62,8 +62,9 @@ int main()
Sound die = LoadSound("resources/die.wav");
Sound growl = LoadSound("resources/gamera.wav");
- // Start playing streaming music
- PlayMusicStream("resources/speeding.ogg");
+ // Load music stream and start playing music
+ Music music = LoadMusicStream("resources/speeding.ogg");
+ PlayMusicStream(music);
// Define scrolling variables
int backScrolling = 0;
@@ -127,6 +128,8 @@ int main()
{
// Update
//----------------------------------------------------------------------------------
+ UpdateMusicStream(music); // Refill music stream buffers (if required)
+
framesCounter++;
// Sea color tint effect
@@ -483,10 +486,10 @@ int main()
UnloadSound(die);
UnloadSound(growl);
- StopMusicStream(); // Stop music
- CloseAudioDevice(); // Close audio device
+ UnloadMusicStream(music); // Unload music
+ CloseAudioDevice(); // Close audio device
- CloseWindow(); // Close window and OpenGL context
+ CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
diff --git a/games/drturtle/drturtle_final_web.c b/games/drturtle/drturtle_final_web.c
index 25f4074b..bec7ebd0 100644
--- a/games/drturtle/drturtle_final_web.c
+++ b/games/drturtle/drturtle_final_web.c
@@ -12,7 +12,7 @@
*
* Enjoy using raylib. :)
*
-* This game has been created using raylib 1.1 (www.raylib.com)
+* This game has been created using raylib 1.6 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - [email protected])
@@ -54,6 +54,8 @@ Sound eat;
Sound die;
Sound growl;
+Music music;
+
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
@@ -124,8 +126,9 @@ int main()
die = LoadSound("resources/die.wav");
growl = LoadSound("resources/gamera.wav");
- // Start playing streaming music
- PlayMusicStream("resources/speeding.ogg");
+ // Load music stream and start playing music
+ music = LoadMusicStream("resources/speeding.ogg");
+ PlayMusicStream(music);
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
@@ -190,10 +193,10 @@ int main()
UnloadSound(die);
UnloadSound(growl);
- StopMusicStream(); // Stop music
- CloseAudioDevice(); // Close audio device
+ UnloadMusicStream(music); // Unload music
+ CloseAudioDevice(); // Close audio device
- CloseWindow(); // Close window and OpenGL context
+ CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
@@ -206,8 +209,8 @@ void UpdateDrawFrame(void)
{
// Update
//----------------------------------------------------------------------------------
- UpdateMusicStream();
-
+ UpdateMusicStream(music); // Refill music stream buffers (if required)
+
framesCounter++;
// Sea color tint effect
diff --git a/games/just_do/just_do.c b/games/just_do/just_do.c
index beac9e14..811150d3 100644
--- a/games/just_do/just_do.c
+++ b/games/just_do/just_do.c
@@ -6,7 +6,7 @@
*
* Developed by: Ramon Santamaria (Ray San)
*
-* This game has been created using raylib (www.raylib.com)
+* This game has been created using raylib 1.6 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* raylib - Copyright (c) 2015 Ramon Santamaria (Ray San - [email protected])
@@ -23,7 +23,7 @@
//----------------------------------------------------------------------------------
// Global Variables Definition (local to this module)
//----------------------------------------------------------------------------------
-const int screenWidth = 1280; // Moved to screens.h
+const int screenWidth = 1280; // Moved to screens.h
const int screenHeight = 720; // Moved to screens.h
// Required variables to manage screen transitions (fade-in, fade-out)
@@ -35,6 +35,7 @@ int transToScreen = -1;
int framesCounter = 0;
//static Sound levelWin;
+Music music;
//----------------------------------------------------------------------------------
// Local Functions Declaration
@@ -57,10 +58,11 @@ int main(void)
//SetupFlags(FLAG_FULLSCREEN_MODE);
InitWindow(screenWidth, screenHeight, windowTitle);
- // TODO: Load global data here (assets that must be available in all screens, i.e. fonts)
+ // Load global data here (assets that must be available in all screens, i.e. fonts)
InitAudioDevice();
levelWin = LoadSound("resources/win.wav");
+ music = LoadMusicStream("resources/ambient.ogg");
// Setup and Init first screen
currentScreen = LOGO;
@@ -85,8 +87,9 @@ int main(void)
// De-Initialization
//--------------------------------------------------------------------------------------
- // TODO: Unload all global loaded data (i.e. fonts) here!
+ // Unload all global loaded data (i.e. fonts) here!
UnloadSound(levelWin);
+ UnloadMusicStream(music);
CloseAudioDevice();
@@ -197,6 +200,8 @@ void UpdateDrawFrame(void)
InitLevel08Screen();
}
+ UpdateMusicStream(music);
+
switch(currentScreen)
{
case LOGO:
@@ -209,8 +214,8 @@ void UpdateDrawFrame(void)
TransitionToScreen(LEVEL00);
InitLevel00Screen();
- PlayMusicStream("resources/ambient.ogg");
- SetMusicVolume(0.6f);
+ PlayMusicStream(music);
+ SetMusicVolume(music, 0.6f);
}
} break;
case LEVEL00:
diff --git a/games/light_my_ritual/light_my_ritual.c b/games/light_my_ritual/light_my_ritual.c
index 0f1dc47e..000eca36 100644
--- a/games/light_my_ritual/light_my_ritual.c
+++ b/games/light_my_ritual/light_my_ritual.c
@@ -35,6 +35,8 @@ bool onTransition = false;
bool transFadeOut = false;
int transFromScreen = -1;
int transToScreen = -1;
+
+static Music music;
//----------------------------------------------------------------------------------
// Local Functions Declaration
@@ -66,11 +68,13 @@ int main(void)
UnloadImage(image); // Unload image from CPU memory (RAM)
- //PlayMusicStream("resources/audio/come_play_with_me.ogg");
-
font = LoadSpriteFont("resources/font_arcadian.png");
//doors = LoadTexture("resources/textures/doors.png");
//sndDoor = LoadSound("resources/audio/door.ogg");
+
+ music = LoadMusicStream("resources/audio/ambient.ogg");
+ PlayMusicStream(music);
+ SetMusicVolume(music, 1.0f);
// Setup and Init first screen
currentScreen = LOGO_RL;
@@ -105,6 +109,8 @@ int main(void)
UnloadSpriteFont(font);
//UnloadSound(sndDoor);
+ UnloadMusicStream(music);
+
free(lightsMap);
CloseAudioDevice();
@@ -218,13 +224,17 @@ void UpdateDrawFrame(void)
rlUpdateLogoScreen();
if (rlFinishLogoScreen()) TransitionToScreen(TITLE);
-
+
} break;
case TITLE:
{
UpdateTitleScreen();
- if (FinishTitleScreen() == 1) TransitionToScreen(GAMEPLAY);
+ if (FinishTitleScreen() == 1)
+ {
+ StopMusicStream(music);
+ TransitionToScreen(GAMEPLAY);
+ }
} break;
case GAMEPLAY:
@@ -244,7 +254,7 @@ void UpdateDrawFrame(void)
UpdateTransition();
}
- UpdateMusicStream();
+ if (currentScreen != GAMEPLAY) UpdateMusicStream(music);
//----------------------------------------------------------------------------------
// Draw
diff --git a/games/light_my_ritual/screens/screen_gameplay.c b/games/light_my_ritual/screens/screen_gameplay.c
index b91d2545..c1779f73 100644
--- a/games/light_my_ritual/screens/screen_gameplay.c
+++ b/games/light_my_ritual/screens/screen_gameplay.c
@@ -64,7 +64,7 @@ typedef struct Enemy {
Color color;
} Enemy;
-typedef struct Light {
+typedef struct LightSpot {
Vector2 position;
int radius;
int requiredEnergy;
@@ -74,7 +74,7 @@ typedef struct Light {
int framesCounter;
int currentFrame;
Rectangle frameRec;
-} Light;
+} LightSpot;
typedef enum { LEVEL_I, LEVEL_II, LEVEL_III, LEVEL_FINISHED } LightedLevel;
@@ -92,9 +92,9 @@ static bool pause;
static Player player;
-static Light lightsI[MAX_LIGHTS_I];
-static Light lightsII[MAX_LIGHTS_II];
-static Light lightsIII[MAX_LIGHTS_III];
+static LightSpot lightsI[MAX_LIGHTS_I];
+static LightSpot lightsII[MAX_LIGHTS_II];
+static LightSpot lightsIII[MAX_LIGHTS_III];
static Enemy enemies[MAX_ENEMIES];
@@ -133,6 +133,8 @@ static Rectangle lightOff, lightOn;
static Sound fxLightOn, fxLightOff;
+static Music music;
+
// Debug variables
static bool enemiesStopped;
@@ -286,7 +288,8 @@ void InitGameplayScreen(void)
enemiesStopped = false;
- PlayMusicStream("resources/audio/ritual.ogg");
+ music = LoadMusicStream("resources/audio/ritual.ogg");
+ PlayMusicStream(music);
}
// Gameplay Screen Update logic
@@ -549,10 +552,12 @@ void UpdateGameplayScreen(void)
{
alphaRitual += 0.02f;
- SetMusicVolume(1.0f - alphaRitual);
+ SetMusicVolume(music, 1.0f - alphaRitual);
if (alphaRitual > 1.0f) finishScreen = 1;
}
+
+ UpdateMusicStream(music);
}
// Gameplay Screen Draw logic
@@ -757,6 +762,8 @@ void UnloadGameplayScreen(void)
// Unload sounds
UnloadSound(fxLightOn);
UnloadSound(fxLightOff);
+
+ UnloadMusicStream(music);
}
// Gameplay Screen should finish?
diff --git a/games/light_my_ritual/screens/screen_logo_raylib.c b/games/light_my_ritual/screens/screen_logo_raylib.c
index 40157b10..f21055d7 100644
--- a/games/light_my_ritual/screens/screen_logo_raylib.c
+++ b/games/light_my_ritual/screens/screen_logo_raylib.c
@@ -75,9 +75,6 @@ void rlInitLogoScreen(void)
state = 0;
alpha = 1.0f;
-
- PlayMusicStream("resources/audio/ambient.ogg");
- SetMusicVolume(1.0f);
}
// Logo Screen Update logic
@@ -204,7 +201,7 @@ void rlDrawLogoScreen(void)
// Logo Screen Unload logic
void rlUnloadLogoScreen(void)
{
- // TODO: Unload LOGO screen variables here!
+ // Unload LOGO screen variables here!
}
// Logo Screen should finish?
diff --git a/games/makefile b/games/makefile
index 2d992896..c48e4d68 100644
--- a/games/makefile
+++ b/games/makefile
@@ -86,8 +86,6 @@ else
# external libraries headers
# GLFW3
INCLUDES += -I../external/glfw3/include
-# GLEW - Not required any more, replaced by GLAD
- #INCLUDES += -I../external/glew/include
# OpenAL Soft
INCLUDES += -I../external/openal_soft/include
endif
@@ -103,8 +101,6 @@ else
ifneq ($(PLATFORM_OS),OSX)
# OpenAL Soft
LFLAGS += -L../external/openal_soft/lib/$(LIBPATH)
- # GLEW: Not used, replaced by GLAD
- #LFLAGS += -L../../external/glew/lib/$(LIBPATH)
endif
endif
@@ -115,9 +111,9 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# libraries for Debian GNU/Linux desktop compiling
# requires the following packages:
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
- LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lm -pthread
- # on XWindow could require also below libraries, just uncomment
- #LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
+ LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lm -lpthread -ldl
+ # on XWindow could require also below libraries:
+ LIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
else
ifeq ($(PLATFORM_OS),OSX)
# libraries for OS X 10.9 desktop compiling
diff --git a/games/raylib_demo/raylib_demo.c b/games/raylib_demo/raylib_demo.c
index 22213b46..722d8ce6 100644
--- a/games/raylib_demo/raylib_demo.c
+++ b/games/raylib_demo/raylib_demo.c
@@ -123,6 +123,8 @@ Model cat;
Sound fxWav;
Sound fxOgg;
+Music music;
+
Vector2 soundBallsPosition[MAX_BALLS];
Color soundBallsColor[MAX_BALLS];
bool soundBallsActive[MAX_BALLS];
@@ -203,11 +205,13 @@ int main()
catTexture = LoadTexture("resources/catsham.png"); // Load model texture
cat = LoadModel("resources/cat.obj"); // Load OBJ model
- cat.material.texDiffuse = texture; // Set cat model diffuse texture
+ cat.material.texDiffuse = catTexture; // Set cat model diffuse texture
fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file
fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file
+ music = LoadMusicStream("resources/audio/guitar_noodling.ogg"); // Load music
+
for (int i = 0; i < MAX_BALLS; i++)
{
soundBallsPosition[i] = (Vector2){ 650 + 560/2 + GetRandomValue(-280, 280), 220 + 200 + GetRandomValue(-200, 200) };
@@ -267,6 +271,8 @@ int main()
UnloadSound(fxWav);
UnloadSound(fxOgg);
+
+ UnloadMusicStream(music);
CloseAudioDevice();
@@ -464,11 +470,11 @@ void UpdateDrawOneFrame(void)
if (selectedModule == AUDIO)
{
- if (IsKeyPressed(KEY_SPACE) && !MusicIsPlaying()) PlayMusicStream("resources/audio/guitar_noodling.ogg"); // Play music stream
+ if (IsKeyPressed(KEY_SPACE) && !IsMusicPlaying(music)) PlayMusicStream(music); // Play music stream
if (IsKeyPressed('S'))
{
- StopMusicStream();
+ StopMusicStream(music);
timePlayed = 0.0f;
for (int i = 0; i < MAX_BALLS; i++)
@@ -482,9 +488,11 @@ void UpdateDrawOneFrame(void)
}
}
- if (MusicIsPlaying())
+ if (IsMusicPlaying(music))
{
- timePlayed = GetMusicTimePlayed() / GetMusicTimeLength() * 100 * 4;
+ UpdateMusicStream(music);
+
+ timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*100*4;
if ((framesCounter%10) == 0)
{
@@ -842,7 +850,7 @@ void UpdateDrawOneFrame(void)
DrawRectangle(150, 390, 400, 12, LIGHTGRAY);
DrawRectangle(150, 390, (int)timePlayed, 12, MAROON);
- if (MusicIsPlaying())
+ if (IsMusicPlaying(music))
{
DrawText("PRESS 'S' to STOP PLAYING MUSIC", 165, 425, 20, GRAY);
diff --git a/games/skully_escape/skully_escape.c b/games/skully_escape/skully_escape.c
index 22cc04e4..83f9732b 100644
--- a/games/skully_escape/skully_escape.c
+++ b/games/skully_escape/skully_escape.c
@@ -2,7 +2,7 @@
*
* SKULLY ESCAPE [KING GAME JAM 2015]
*
-* This game has been created using raylib (www.raylib.com)
+* This game has been created using raylib 1.6 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (Ray San - [email protected])
@@ -32,6 +32,8 @@ int transFromScreen = -1;
int transToScreen = -1;
static int framesCounter = 0;
+
+Music music;
//----------------------------------------------------------------------------------
// Local Functions Declaration
@@ -57,7 +59,8 @@ int main(void)
// Global data loading (assets that must be available in all screens, i.e. fonts)
InitAudioDevice();
- PlayMusicStream("resources/audio/come_play_with_me.ogg");
+ music = LoadMusicStream("resources/audio/come_play_with_me.ogg");
+ PlayMusicStream(music);
font = LoadSpriteFont("resources/textures/alagard.png");
doors = LoadTexture("resources/textures/doors.png");
@@ -93,6 +96,8 @@ int main(void)
UnloadSound(sndDoor);
UnloadSound(sndScream);
+ UnloadMusicStream(music);
+
CloseAudioDevice();
CloseWindow(); // Close window and OpenGL context
@@ -368,7 +373,7 @@ void UpdateDrawFrame(void)
UpdateTransition();
}
- UpdateMusicStream();
+ UpdateMusicStream(music);
//----------------------------------------------------------------------------------
// Draw
diff --git a/project/vs2015/examples/core_basic_window.vcxproj b/project/vs2015/examples/core_basic_window.vcxproj
new file mode 100644
index 00000000..2ae68c2d
--- /dev/null
+++ b/project/vs2015/examples/core_basic_window.vcxproj
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{0981CA98-E4A5-4DF1-987F-A41D09131EFC}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>core_basic_window</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <ProjectName>core_basic_window</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <CompileAs>CompileAsC</CompileAs>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(SolutionDir)external\glfw3\lib\win32;$(SolutionDir)external\openal_soft\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>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)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\examples\core_basic_window.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\raylib\raylib.vcxproj">
+ <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/project/vs2015/examples/core_basic_window_cpp.vcxproj b/project/vs2015/examples/core_basic_window_cpp.vcxproj
new file mode 100644
index 00000000..29e0c616
--- /dev/null
+++ b/project/vs2015/examples/core_basic_window_cpp.vcxproj
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{B655E850-3322-42F7-941D-6AC18FD66CA1}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>raylib_example_cpp</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ <ProjectName>core_basic_window_cpp</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <CompileAs>CompileAsCpp</CompileAs>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>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)</AdditionalDependencies>
+ <AdditionalLibraryDirectories>$(SolutionDir)external\glfw3\lib\win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\raylib\raylib.vcxproj">
+ <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\examples\core_basic_window.cpp" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/project/vs2015/external/glfw3/COPYING.txt b/project/vs2015/external/glfw3/COPYING.txt
new file mode 100644
index 00000000..ad16462a
--- /dev/null
+++ b/project/vs2015/external/glfw3/COPYING.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2002-2006 Marcus Geelnard
+Copyright (c) 2006-2016 Camilla Berglund <[email protected]>
+
+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
new file mode 100644
index 00000000..5a0c4508
--- /dev/null
+++ b/project/vs2015/external/glfw3/include/GLFW/glfw3.h
@@ -0,0 +1,4235 @@
+/*************************************************************************
+ * 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 <[email protected]>
+ *
+ * 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 <stddef.h>
+#include <stdint.h>
+
+/* Include the chosen client API headers.
+ */
+#if defined(__APPLE__)
+ #if defined(GLFW_INCLUDE_GLCOREARB)
+ #include <OpenGL/gl3.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <OpenGL/gl3ext.h>
+ #endif
+ #elif !defined(GLFW_INCLUDE_NONE)
+ #if !defined(GLFW_INCLUDE_GLEXT)
+ #define GL_GLEXT_LEGACY
+ #endif
+ #include <OpenGL/gl.h>
+ #endif
+ #if defined(GLFW_INCLUDE_GLU)
+ #include <OpenGL/glu.h>
+ #endif
+#else
+ #if defined(GLFW_INCLUDE_GLCOREARB)
+ #include <GL/glcorearb.h>
+ #elif defined(GLFW_INCLUDE_ES1)
+ #include <GLES/gl.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES/glext.h>
+ #endif
+ #elif defined(GLFW_INCLUDE_ES2)
+ #include <GLES2/gl2.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES2/gl2ext.h>
+ #endif
+ #elif defined(GLFW_INCLUDE_ES3)
+ #include <GLES3/gl3.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES2/gl2ext.h>
+ #endif
+ #elif defined(GLFW_INCLUDE_ES31)
+ #include <GLES3/gl31.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GLES2/gl2ext.h>
+ #endif
+ #elif defined(GLFW_INCLUDE_VULKAN)
+ #include <vulkan/vulkan.h>
+ #elif !defined(GLFW_INCLUDE_NONE)
+ #include <GL/gl.h>
+ #if defined(GLFW_INCLUDE_GLEXT)
+ #include <GL/glext.h>
+ #endif
+ #endif
+ #if defined(GLFW_INCLUDE_GLU)
+ #include <GL/glu.h>
+ #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((2<sup>64</sup> - 1) / 10<sup>9</sup>) 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&nbsp;/&nbsp;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/include/GLFW/glfw3native.h b/project/vs2015/external/glfw3/include/GLFW/glfw3native.h
new file mode 100644
index 00000000..30e1a570
--- /dev/null
+++ b/project/vs2015/external/glfw3/include/GLFW/glfw3native.h
@@ -0,0 +1,456 @@
+/*************************************************************************
+ * 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 <[email protected]>
+ *
+ * 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 <windows.h>
+#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
+ #include <ApplicationServices/ApplicationServices.h>
+ #if defined(__OBJC__)
+ #import <Cocoa/Cocoa.h>
+ #else
+ typedef void* id;
+ #endif
+#elif defined(GLFW_EXPOSE_NATIVE_X11)
+ #include <X11/Xlib.h>
+ #include <X11/extensions/Xrandr.h>
+#elif defined(GLFW_EXPOSE_NATIVE_WAYLAND)
+ #include <wayland-client.h>
+#elif defined(GLFW_EXPOSE_NATIVE_MIR)
+ #include <mir_toolkit/mir_client_library.h>
+#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 <GL/glx.h>
+#endif
+#if defined(GLFW_EXPOSE_NATIVE_EGL)
+ #include <EGL/egl.h>
+#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/project/vs2015/external/glfw3/lib/win32/glfw3.dll b/project/vs2015/external/glfw3/lib/win32/glfw3.dll
new file mode 100644
index 00000000..3e2a7f35
--- /dev/null
+++ b/project/vs2015/external/glfw3/lib/win32/glfw3.dll
Binary files differ
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3.lib b/project/vs2015/external/glfw3/lib/win32/glfw3.lib
new file mode 100644
index 00000000..bec8cfc9
--- /dev/null
+++ b/project/vs2015/external/glfw3/lib/win32/glfw3.lib
Binary files differ
diff --git a/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib b/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib
new file mode 100644
index 00000000..8e87d64a
--- /dev/null
+++ b/project/vs2015/external/glfw3/lib/win32/glfw3dll.lib
Binary files differ
diff --git a/project/vs2015/external/lua/include/lauxlib.h b/project/vs2015/external/lua/include/lauxlib.h
new file mode 100644
index 00000000..ddb7c228
--- /dev/null
+++ b/project/vs2015/external/lua/include/lauxlib.h
@@ -0,0 +1,256 @@
+/*
+** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lauxlib_h
+#define lauxlib_h
+
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "lua.h"
+
+
+
+/* extra error code for 'luaL_load' */
+#define LUA_ERRFILE (LUA_ERRERR+1)
+
+
+typedef struct luaL_Reg {
+ const char *name;
+ lua_CFunction func;
+} luaL_Reg;
+
+
+#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number))
+
+LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
+#define luaL_checkversion(L) \
+ luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
+
+LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
+LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
+LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
+LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
+ size_t *l);
+LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
+ const char *def, size_t *l);
+LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
+LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
+
+LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
+LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
+ lua_Integer def);
+
+LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
+LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
+
+LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
+LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
+LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
+LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
+
+LUALIB_API void (luaL_where) (lua_State *L, int lvl);
+LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
+
+LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
+ const char *const lst[]);
+
+LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
+LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
+
+/* predefined references */
+#define LUA_NOREF (-2)
+#define LUA_REFNIL (-1)
+
+LUALIB_API int (luaL_ref) (lua_State *L, int t);
+LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
+
+LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
+ const char *mode);
+
+#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
+
+LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
+ const char *name, const char *mode);
+LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
+
+LUALIB_API lua_State *(luaL_newstate) (void);
+
+LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
+
+LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
+ const char *r);
+
+LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
+
+LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
+
+LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
+ const char *msg, int level);
+
+LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
+ lua_CFunction openf, int glb);
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+
+#define luaL_newlibtable(L,l) \
+ lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
+
+#define luaL_newlib(L,l) \
+ (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+
+#define luaL_argcheck(L, cond,arg,extramsg) \
+ ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
+#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
+#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
+
+#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
+
+#define luaL_dofile(L, fn) \
+ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_dostring(L, s) \
+ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
+
+#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+
+#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+typedef struct luaL_Buffer {
+ char *b; /* buffer address */
+ size_t size; /* buffer size */
+ size_t n; /* number of characters in buffer */
+ lua_State *L;
+ char initb[LUAL_BUFFERSIZE]; /* initial buffer */
+} luaL_Buffer;
+
+
+#define luaL_addchar(B,c) \
+ ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
+ ((B)->b[(B)->n++] = (c)))
+
+#define luaL_addsize(B,s) ((B)->n += (s))
+
+LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
+LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
+
+#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** File handles for IO library
+** =======================================================
+*/
+
+/*
+** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
+** initial structure 'luaL_Stream' (it may contain other fields
+** after that initial structure).
+*/
+
+#define LUA_FILEHANDLE "FILE*"
+
+
+typedef struct luaL_Stream {
+ FILE *f; /* stream (NULL for incompletely created streams) */
+ lua_CFunction closef; /* to close stream (NULL for closed streams) */
+} luaL_Stream;
+
+/* }====================================================== */
+
+
+
+/* compatibility with old module system */
+#if defined(LUA_COMPAT_MODULE)
+
+LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
+ int sizehint);
+LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
+ const luaL_Reg *l, int nup);
+
+#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
+
+#endif
+
+
+/*
+** {==================================================================
+** "Abstraction Layer" for basic report of messages and errors
+** ===================================================================
+*/
+
+/* print a string */
+#if !defined(lua_writestring)
+#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
+#endif
+
+/* print a newline and flush the output */
+#if !defined(lua_writeline)
+#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
+#endif
+
+/* print an error message */
+#if !defined(lua_writestringerror)
+#define lua_writestringerror(s,p) \
+ (fprintf(stderr, (s), (p)), fflush(stderr))
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {============================================================
+** Compatibility with deprecated conversions
+** =============================================================
+*/
+#if defined(LUA_COMPAT_APIINTCASTS)
+
+#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
+#define luaL_optunsigned(L,a,d) \
+ ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
+
+#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
+#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
+
+#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
+#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
+
+#endif
+/* }============================================================ */
+
+
+
+#endif
+
+
diff --git a/project/vs2015/external/lua/include/lua.h b/project/vs2015/external/lua/include/lua.h
new file mode 100644
index 00000000..f78899fc
--- /dev/null
+++ b/project/vs2015/external/lua/include/lua.h
@@ -0,0 +1,486 @@
+/*
+** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $
+** Lua - A Scripting Language
+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+** See Copyright Notice at the end of this file
+*/
+
+
+#ifndef lua_h
+#define lua_h
+
+#include <stdarg.h>
+#include <stddef.h>
+
+
+#include "luaconf.h"
+
+
+#define LUA_VERSION_MAJOR "5"
+#define LUA_VERSION_MINOR "3"
+#define LUA_VERSION_NUM 503
+#define LUA_VERSION_RELEASE "3"
+
+#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
+#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio"
+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
+
+
+/* mark for precompiled code ('<esc>Lua') */
+#define LUA_SIGNATURE "\x1bLua"
+
+/* option for multiple returns in 'lua_pcall' and 'lua_call' */
+#define LUA_MULTRET (-1)
+
+
+/*
+** Pseudo-indices
+** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
+** space after that to help overflow detection)
+*/
+#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
+#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
+
+
+/* thread status */
+#define LUA_OK 0
+#define LUA_YIELD 1
+#define LUA_ERRRUN 2
+#define LUA_ERRSYNTAX 3
+#define LUA_ERRMEM 4
+#define LUA_ERRGCMM 5
+#define LUA_ERRERR 6
+
+
+typedef struct lua_State lua_State;
+
+
+/*
+** basic types
+*/
+#define LUA_TNONE (-1)
+
+#define LUA_TNIL 0
+#define LUA_TBOOLEAN 1
+#define LUA_TLIGHTUSERDATA 2
+#define LUA_TNUMBER 3
+#define LUA_TSTRING 4
+#define LUA_TTABLE 5
+#define LUA_TFUNCTION 6
+#define LUA_TUSERDATA 7
+#define LUA_TTHREAD 8
+
+#define LUA_NUMTAGS 9
+
+
+
+/* minimum Lua stack available to a C function */
+#define LUA_MINSTACK 20
+
+
+/* predefined values in the registry */
+#define LUA_RIDX_MAINTHREAD 1
+#define LUA_RIDX_GLOBALS 2
+#define LUA_RIDX_LAST LUA_RIDX_GLOBALS
+
+
+/* type of numbers in Lua */
+typedef LUA_NUMBER lua_Number;
+
+
+/* type for integer functions */
+typedef LUA_INTEGER lua_Integer;
+
+/* unsigned integer type */
+typedef LUA_UNSIGNED lua_Unsigned;
+
+/* type for continuation-function contexts */
+typedef LUA_KCONTEXT lua_KContext;
+
+
+/*
+** Type for C functions registered with Lua
+*/
+typedef int (*lua_CFunction) (lua_State *L);
+
+/*
+** Type for continuation functions
+*/
+typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
+
+
+/*
+** Type for functions that read/write blocks when loading/dumping Lua chunks
+*/
+typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
+
+typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
+
+
+/*
+** Type for memory-allocation functions
+*/
+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+
+
+
+/*
+** generic extra include file
+*/
+#if defined(LUA_USER_H)
+#include LUA_USER_H
+#endif
+
+
+/*
+** RCS ident string
+*/
+extern const char lua_ident[];
+
+
+/*
+** state manipulation
+*/
+LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+LUA_API void (lua_close) (lua_State *L);
+LUA_API lua_State *(lua_newthread) (lua_State *L);
+
+LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
+
+
+LUA_API const lua_Number *(lua_version) (lua_State *L);
+
+
+/*
+** basic stack manipulation
+*/
+LUA_API int (lua_absindex) (lua_State *L, int idx);
+LUA_API int (lua_gettop) (lua_State *L);
+LUA_API void (lua_settop) (lua_State *L, int idx);
+LUA_API void (lua_pushvalue) (lua_State *L, int idx);
+LUA_API void (lua_rotate) (lua_State *L, int idx, int n);
+LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx);
+LUA_API int (lua_checkstack) (lua_State *L, int n);
+
+LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
+
+
+/*
+** access functions (stack -> C)
+*/
+
+LUA_API int (lua_isnumber) (lua_State *L, int idx);
+LUA_API int (lua_isstring) (lua_State *L, int idx);
+LUA_API int (lua_iscfunction) (lua_State *L, int idx);
+LUA_API int (lua_isinteger) (lua_State *L, int idx);
+LUA_API int (lua_isuserdata) (lua_State *L, int idx);
+LUA_API int (lua_type) (lua_State *L, int idx);
+LUA_API const char *(lua_typename) (lua_State *L, int tp);
+
+LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
+LUA_API int (lua_toboolean) (lua_State *L, int idx);
+LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
+LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
+LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
+LUA_API void *(lua_touserdata) (lua_State *L, int idx);
+LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
+LUA_API const void *(lua_topointer) (lua_State *L, int idx);
+
+
+/*
+** Comparison and arithmetic functions
+*/
+
+#define LUA_OPADD 0 /* ORDER TM, ORDER OP */
+#define LUA_OPSUB 1
+#define LUA_OPMUL 2
+#define LUA_OPMOD 3
+#define LUA_OPPOW 4
+#define LUA_OPDIV 5
+#define LUA_OPIDIV 6
+#define LUA_OPBAND 7
+#define LUA_OPBOR 8
+#define LUA_OPBXOR 9
+#define LUA_OPSHL 10
+#define LUA_OPSHR 11
+#define LUA_OPUNM 12
+#define LUA_OPBNOT 13
+
+LUA_API void (lua_arith) (lua_State *L, int op);
+
+#define LUA_OPEQ 0
+#define LUA_OPLT 1
+#define LUA_OPLE 2
+
+LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
+
+
+/*
+** push functions (C -> stack)
+*/
+LUA_API void (lua_pushnil) (lua_State *L);
+LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
+LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len);
+LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
+LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
+ va_list argp);
+LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
+LUA_API void (lua_pushboolean) (lua_State *L, int b);
+LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
+LUA_API int (lua_pushthread) (lua_State *L);
+
+
+/*
+** get functions (Lua -> stack)
+*/
+LUA_API int (lua_getglobal) (lua_State *L, const char *name);
+LUA_API int (lua_gettable) (lua_State *L, int idx);
+LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n);
+LUA_API int (lua_rawget) (lua_State *L, int idx);
+LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
+LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
+
+LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
+LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
+LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
+LUA_API int (lua_getuservalue) (lua_State *L, int idx);
+
+
+/*
+** set functions (stack -> Lua)
+*/
+LUA_API void (lua_setglobal) (lua_State *L, const char *name);
+LUA_API void (lua_settable) (lua_State *L, int idx);
+LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
+LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n);
+LUA_API void (lua_rawset) (lua_State *L, int idx);
+LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n);
+LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
+LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
+LUA_API void (lua_setuservalue) (lua_State *L, int idx);
+
+
+/*
+** 'load' and 'call' functions (load and run Lua code)
+*/
+LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults,
+ lua_KContext ctx, lua_KFunction k);
+#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
+
+LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
+ lua_KContext ctx, lua_KFunction k);
+#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
+
+LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
+ const char *chunkname, const char *mode);
+
+LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
+
+
+/*
+** coroutine functions
+*/
+LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx,
+ lua_KFunction k);
+LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
+LUA_API int (lua_status) (lua_State *L);
+LUA_API int (lua_isyieldable) (lua_State *L);
+
+#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
+
+
+/*
+** garbage-collection function and options
+*/
+
+#define LUA_GCSTOP 0
+#define LUA_GCRESTART 1
+#define LUA_GCCOLLECT 2
+#define LUA_GCCOUNT 3
+#define LUA_GCCOUNTB 4
+#define LUA_GCSTEP 5
+#define LUA_GCSETPAUSE 6
+#define LUA_GCSETSTEPMUL 7
+#define LUA_GCISRUNNING 9
+
+LUA_API int (lua_gc) (lua_State *L, int what, int data);
+
+
+/*
+** miscellaneous functions
+*/
+
+LUA_API int (lua_error) (lua_State *L);
+
+LUA_API int (lua_next) (lua_State *L, int idx);
+
+LUA_API void (lua_concat) (lua_State *L, int n);
+LUA_API void (lua_len) (lua_State *L, int idx);
+
+LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
+
+LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
+LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
+
+
+
+/*
+** {==============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
+
+#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL)
+#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL)
+
+#define lua_pop(L,n) lua_settop(L, -(n)-1)
+
+#define lua_newtable(L) lua_createtable(L, 0, 0)
+
+#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
+
+#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
+
+#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
+#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
+#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
+#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
+#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
+#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
+#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
+#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
+
+#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
+
+#define lua_pushglobaltable(L) \
+ ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
+
+#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
+
+
+#define lua_insert(L,idx) lua_rotate(L, (idx), 1)
+
+#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
+
+#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
+
+/* }============================================================== */
+
+
+/*
+** {==============================================================
+** compatibility macros for unsigned conversions
+** ===============================================================
+*/
+#if defined(LUA_COMPAT_APIINTCASTS)
+
+#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
+#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is))
+#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL)
+
+#endif
+/* }============================================================== */
+
+/*
+** {======================================================================
+** Debug API
+** =======================================================================
+*/
+
+
+/*
+** Event codes
+*/
+#define LUA_HOOKCALL 0
+#define LUA_HOOKRET 1
+#define LUA_HOOKLINE 2
+#define LUA_HOOKCOUNT 3
+#define LUA_HOOKTAILCALL 4
+
+
+/*
+** Event masks
+*/
+#define LUA_MASKCALL (1 << LUA_HOOKCALL)
+#define LUA_MASKRET (1 << LUA_HOOKRET)
+#define LUA_MASKLINE (1 << LUA_HOOKLINE)
+#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
+
+typedef struct lua_Debug lua_Debug; /* activation record */
+
+
+/* Functions to be called by the debugger in specific events */
+typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+
+
+LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
+LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
+LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
+LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
+
+LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
+LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
+ int fidx2, int n2);
+
+LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
+LUA_API lua_Hook (lua_gethook) (lua_State *L);
+LUA_API int (lua_gethookmask) (lua_State *L);
+LUA_API int (lua_gethookcount) (lua_State *L);
+
+
+struct lua_Debug {
+ int event;
+ const char *name; /* (n) */
+ const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */
+ const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */
+ const char *source; /* (S) */
+ int currentline; /* (l) */
+ int linedefined; /* (S) */
+ int lastlinedefined; /* (S) */
+ unsigned char nups; /* (u) number of upvalues */
+ unsigned char nparams;/* (u) number of parameters */
+ char isvararg; /* (u) */
+ char istailcall; /* (t) */
+ char short_src[LUA_IDSIZE]; /* (S) */
+ /* private part */
+ struct CallInfo *i_ci; /* active function */
+};
+
+/* }====================================================================== */
+
+
+/******************************************************************************
+* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is 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 Software.
+*
+* 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 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
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+
+#endif
diff --git a/project/vs2015/external/lua/include/lua.hpp b/project/vs2015/external/lua/include/lua.hpp
new file mode 100644
index 00000000..ec417f59
--- /dev/null
+++ b/project/vs2015/external/lua/include/lua.hpp
@@ -0,0 +1,9 @@
+// lua.hpp
+// Lua header files for C++
+// <<extern "C">> not supplied automatically because Lua also compiles as C++
+
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
diff --git a/project/vs2015/external/lua/include/luaconf.h b/project/vs2015/external/lua/include/luaconf.h
new file mode 100644
index 00000000..867e9cb1
--- /dev/null
+++ b/project/vs2015/external/lua/include/luaconf.h
@@ -0,0 +1,769 @@
+/*
+** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
+** Configuration file for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef luaconf_h
+#define luaconf_h
+
+#include <limits.h>
+#include <stddef.h>
+
+
+/*
+** ===================================================================
+** Search for "@@" to find all configurable definitions.
+** ===================================================================
+*/
+
+
+/*
+** {====================================================================
+** System Configuration: macros to adapt (if needed) Lua to some
+** particular platform, for instance compiling it with 32-bit numbers or
+** restricting it to C89.
+** =====================================================================
+*/
+
+/*
+@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You
+** can also define LUA_32BITS in the make file, but changing here you
+** ensure that all software connected to Lua will be compiled with the
+** same configuration.
+*/
+/* #define LUA_32BITS */
+
+
+/*
+@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
+** Define it if you want Lua to avoid the use of a few C99 features
+** or Windows-specific features on Windows.
+*/
+/* #define LUA_USE_C89 */
+
+
+/*
+** By default, Lua on Windows use (some) specific Windows features
+*/
+#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_USE_WINDOWS /* enable goodies for regular Windows */
+#endif
+
+
+#if defined(LUA_USE_WINDOWS)
+#define LUA_DL_DLL /* enable support for DLL */
+#define LUA_USE_C89 /* broadly, Windows is C89 */
+#endif
+
+
+#if defined(LUA_USE_LINUX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
+#define LUA_USE_READLINE /* needs some extra libraries */
+#endif
+
+
+#if defined(LUA_USE_MACOSX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
+#define LUA_USE_READLINE /* needs an extra library: -lreadline */
+#endif
+
+
+/*
+@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
+** C89 ('long' and 'double'); Windows always has '__int64', so it does
+** not need to use this case.
+*/
+#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
+#define LUA_C89_NUMBERS
+#endif
+
+
+
+/*
+@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'.
+*/
+/* avoid undefined shifts */
+#if ((INT_MAX >> 15) >> 15) >= 1
+#define LUAI_BITSINT 32
+#else
+/* 'int' always must have at least 16 bits */
+#define LUAI_BITSINT 16
+#endif
+
+
+/*
+@@ LUA_INT_TYPE defines the type for Lua integers.
+@@ LUA_FLOAT_TYPE defines the type for Lua floats.
+** Lua should work fine with any mix of these options (if supported
+** by your C compiler). The usual configurations are 64-bit integers
+** and 'double' (the default), 32-bit integers and 'float' (for
+** restricted platforms), and 'long'/'double' (for C compilers not
+** compliant with C99, which may not have support for 'long long').
+*/
+
+/* predefined options for LUA_INT_TYPE */
+#define LUA_INT_INT 1
+#define LUA_INT_LONG 2
+#define LUA_INT_LONGLONG 3
+
+/* predefined options for LUA_FLOAT_TYPE */
+#define LUA_FLOAT_FLOAT 1
+#define LUA_FLOAT_DOUBLE 2
+#define LUA_FLOAT_LONGDOUBLE 3
+
+#if defined(LUA_32BITS) /* { */
+/*
+** 32-bit integers and 'float'
+*/
+#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
+#define LUA_INT_TYPE LUA_INT_INT
+#else /* otherwise use 'long' */
+#define LUA_INT_TYPE LUA_INT_LONG
+#endif
+#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
+
+#elif defined(LUA_C89_NUMBERS) /* }{ */
+/*
+** largest types available for C89 ('long' and 'double')
+*/
+#define LUA_INT_TYPE LUA_INT_LONG
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
+
+#endif /* } */
+
+
+/*
+** default configuration for 64-bit Lua ('long long' and 'double')
+*/
+#if !defined(LUA_INT_TYPE)
+#define LUA_INT_TYPE LUA_INT_LONGLONG
+#endif
+
+#if !defined(LUA_FLOAT_TYPE)
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
+#endif
+
+/* }================================================================== */
+
+
+
+
+/*
+** {==================================================================
+** Configuration for Paths.
+** ===================================================================
+*/
+
+/*
+@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
+** Lua libraries.
+@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
+** C libraries.
+** CHANGE them if your machine has a non-conventional directory
+** hierarchy or if you want to install your libraries in
+** non-conventional directories.
+*/
+#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#if defined(_WIN32) /* { */
+/*
+** In Windows, any exclamation mark ('!') in the path is replaced by the
+** path of the directory of the executable file of the current process.
+*/
+#define LUA_LDIR "!\\lua\\"
+#define LUA_CDIR "!\\"
+#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\"
+#define LUA_PATH_DEFAULT \
+ LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \
+ LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \
+ ".\\?.lua;" ".\\?\\init.lua"
+#define LUA_CPATH_DEFAULT \
+ LUA_CDIR"?.dll;" \
+ LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
+ LUA_CDIR"loadall.dll;" ".\\?.dll;" \
+ LUA_CDIR"?53.dll;" ".\\?53.dll"
+
+#else /* }{ */
+
+#define LUA_ROOT "/usr/local/"
+#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
+#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
+#define LUA_PATH_DEFAULT \
+ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \
+ "./?.lua;" "./?/init.lua"
+#define LUA_CPATH_DEFAULT \
+ LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so;" \
+ LUA_CDIR"lib?53.so;" "./lib?53.so"
+#endif /* } */
+
+
+/*
+@@ LUA_DIRSEP is the directory separator (for submodules).
+** CHANGE it if your machine does not use "/" as the directory separator
+** and is not Windows. (On Windows Lua automatically uses "\".)
+*/
+#if defined(_WIN32)
+#define LUA_DIRSEP "\\"
+#else
+#define LUA_DIRSEP "/"
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Marks for exported symbols in the C code
+** ===================================================================
+*/
+
+/*
+@@ LUA_API is a mark for all core API functions.
+@@ LUALIB_API is a mark for all auxiliary library functions.
+@@ LUAMOD_API is a mark for all standard library opening functions.
+** CHANGE them if you need to define those functions in some special way.
+** For instance, if you want to create one Windows DLL with the core and
+** the libraries, you may want to use the following definition (define
+** LUA_BUILD_AS_DLL to get it).
+*/
+#if defined(LUA_BUILD_AS_DLL) /* { */
+
+#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
+#define LUA_API __declspec(dllexport)
+#else /* }{ */
+#define LUA_API __declspec(dllimport)
+#endif /* } */
+
+#else /* }{ */
+
+#define LUA_API extern
+
+#endif /* } */
+
+
+/* more often than not the libs go together with the core */
+#define LUALIB_API LUA_API
+#define LUAMOD_API LUALIB_API
+
+
+/*
+@@ LUAI_FUNC is a mark for all extern functions that are not to be
+** exported to outside modules.
+@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
+** that are not to be exported to outside modules (LUAI_DDEF for
+** definitions and LUAI_DDEC for declarations).
+** CHANGE them if you need to mark them in some special way. Elf/gcc
+** (versions 3.2 and later) mark them as "hidden" to optimize access
+** when Lua is compiled as a shared library. Not all elf targets support
+** this attribute. Unfortunately, gcc does not offer a way to check
+** whether the target offers that support, and those without support
+** give a warning about it. To avoid these warnings, change to the
+** default definition.
+*/
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+ defined(__ELF__) /* { */
+#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
+#else /* }{ */
+#define LUAI_FUNC extern
+#endif /* } */
+
+#define LUAI_DDEC LUAI_FUNC
+#define LUAI_DDEF /* empty */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Compatibility with previous versions
+** ===================================================================
+*/
+
+/*
+@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
+@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
+** You can define it to get all options, or change specific options
+** to fit your specific needs.
+*/
+#if defined(LUA_COMPAT_5_2) /* { */
+
+/*
+@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
+** functions in the mathematical library.
+*/
+#define LUA_COMPAT_MATHLIB
+
+/*
+@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'.
+*/
+#define LUA_COMPAT_BITLIB
+
+/*
+@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
+*/
+#define LUA_COMPAT_IPAIRS
+
+/*
+@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
+** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
+** luaL_checkint, luaL_checklong, etc.)
+*/
+#define LUA_COMPAT_APIINTCASTS
+
+#endif /* } */
+
+
+#if defined(LUA_COMPAT_5_1) /* { */
+
+/* Incompatibilities from 5.2 -> 5.3 */
+#define LUA_COMPAT_MATHLIB
+#define LUA_COMPAT_APIINTCASTS
+
+/*
+@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
+** You can replace it with 'table.unpack'.
+*/
+#define LUA_COMPAT_UNPACK
+
+/*
+@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
+** You can replace it with 'package.searchers'.
+*/
+#define LUA_COMPAT_LOADERS
+
+/*
+@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
+** You can call your C function directly (with light C functions).
+*/
+#define lua_cpcall(L,f,u) \
+ (lua_pushcfunction(L, (f)), \
+ lua_pushlightuserdata(L,(u)), \
+ lua_pcall(L,1,0,0))
+
+
+/*
+@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
+** You can rewrite 'log10(x)' as 'log(x, 10)'.
+*/
+#define LUA_COMPAT_LOG10
+
+/*
+@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
+** library. You can rewrite 'loadstring(s)' as 'load(s)'.
+*/
+#define LUA_COMPAT_LOADSTRING
+
+/*
+@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
+*/
+#define LUA_COMPAT_MAXN
+
+/*
+@@ The following macros supply trivial compatibility for some
+** changes in the API. The macros themselves document how to
+** change your code to avoid using them.
+*/
+#define lua_strlen(L,i) lua_rawlen(L, (i))
+
+#define lua_objlen(L,i) lua_rawlen(L, (i))
+
+#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
+
+/*
+@@ LUA_COMPAT_MODULE controls compatibility with previous
+** module functions 'module' (Lua) and 'luaL_register' (C).
+*/
+#define LUA_COMPAT_MODULE
+
+#endif /* } */
+
+
+/*
+@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
+@@ a float mark ('.0').
+** This macro is not on by default even in compatibility mode,
+** because this is not really an incompatibility.
+*/
+/* #define LUA_COMPAT_FLOATSTRING */
+
+/* }================================================================== */
+
+
+
+/*
+** {==================================================================
+** Configuration for Numbers.
+** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
+** satisfy your needs.
+** ===================================================================
+*/
+
+/*
+@@ LUA_NUMBER is the floating-point type used by Lua.
+@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+@@ over a floating number.
+@@ l_mathlim(x) corrects limit name 'x' to the proper float type
+** by prefixing it with one of FLT/DBL/LDBL.
+@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
+@@ LUA_NUMBER_FMT is the format for writing floats.
+@@ lua_number2str converts a float to a string.
+@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
+@@ l_floor takes the floor of a float.
+@@ lua_str2number converts a decimal numeric string to a number.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define l_floor(x) (l_mathop(floor)(x))
+
+#define lua_number2str(s,sz,n) l_sprintf((s), sz, LUA_NUMBER_FMT, (n))
+
+/*
+@@ lua_numbertointeger converts a float number to an integer, or
+** returns 0 if float is not within the range of a lua_Integer.
+** (The range comparisons are tricky because of rounding. The tests
+** here assume a two-complement representation, where MININTEGER always
+** has an exact representation as a float; MAXINTEGER may not have one,
+** and therefore its conversion to float may have an ill-defined value.)
+*/
+#define lua_numbertointeger(n,p) \
+ ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
+ (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
+ (*(p) = (LUA_INTEGER)(n), 1))
+
+
+/* now the variable definitions */
+
+#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
+
+#define LUA_NUMBER float
+
+#define l_mathlim(n) (FLT_##n)
+
+#define LUAI_UACNUMBER double
+
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_FMT "%.7g"
+
+#define l_mathop(op) op##f
+
+#define lua_str2number(s,p) strtof((s), (p))
+
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
+
+#define LUA_NUMBER long double
+
+#define l_mathlim(n) (LDBL_##n)
+
+#define LUAI_UACNUMBER long double
+
+#define LUA_NUMBER_FRMLEN "L"
+#define LUA_NUMBER_FMT "%.19Lg"
+
+#define l_mathop(op) op##l
+
+#define lua_str2number(s,p) strtold((s), (p))
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
+
+#define LUA_NUMBER double
+
+#define l_mathlim(n) (DBL_##n)
+
+#define LUAI_UACNUMBER double
+
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_FMT "%.14g"
+
+#define l_mathop(op) op
+
+#define lua_str2number(s,p) strtod((s), (p))
+
+#else /* }{ */
+
+#error "numeric float type not defined"
+
+#endif /* } */
+
+
+
+/*
+@@ LUA_INTEGER is the integer type used by Lua.
+**
+@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
+**
+@@ LUAI_UACINT is the result of an 'usual argument conversion'
+@@ over a lUA_INTEGER.
+@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
+@@ LUA_INTEGER_FMT is the format for writing integers.
+@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
+@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
+@@ lua_integer2str converts an integer to a string.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
+#define lua_integer2str(s,sz,n) l_sprintf((s), sz, LUA_INTEGER_FMT, (n))
+
+#define LUAI_UACINT LUA_INTEGER
+
+/*
+** use LUAI_UACINT here to avoid problems with promotions (which
+** can turn a comparison between unsigneds into a signed comparison)
+*/
+#define LUA_UNSIGNED unsigned LUAI_UACINT
+
+
+/* now the variable definitions */
+
+#if LUA_INT_TYPE == LUA_INT_INT /* { int */
+
+#define LUA_INTEGER int
+#define LUA_INTEGER_FRMLEN ""
+
+#define LUA_MAXINTEGER INT_MAX
+#define LUA_MININTEGER INT_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
+
+#define LUA_INTEGER long
+#define LUA_INTEGER_FRMLEN "l"
+
+#define LUA_MAXINTEGER LONG_MAX
+#define LUA_MININTEGER LONG_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
+
+/* use presence of macro LLONG_MAX as proxy for C99 compliance */
+#if defined(LLONG_MAX) /* { */
+/* use ISO C99 stuff */
+
+#define LUA_INTEGER long long
+#define LUA_INTEGER_FRMLEN "ll"
+
+#define LUA_MAXINTEGER LLONG_MAX
+#define LUA_MININTEGER LLONG_MIN
+
+#elif defined(LUA_USE_WINDOWS) /* }{ */
+/* in Windows, can use specific Windows types */
+
+#define LUA_INTEGER __int64
+#define LUA_INTEGER_FRMLEN "I64"
+
+#define LUA_MAXINTEGER _I64_MAX
+#define LUA_MININTEGER _I64_MIN
+
+#else /* }{ */
+
+#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
+ or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
+
+#endif /* } */
+
+#else /* }{ */
+
+#error "numeric integer type not defined"
+
+#endif /* } */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Dependencies with C99 and other C details
+** ===================================================================
+*/
+
+/*
+@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
+** (All uses in Lua have only one format item.)
+*/
+#if !defined(LUA_USE_C89)
+#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i)
+#else
+#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i))
+#endif
+
+
+/*
+@@ lua_strx2number converts an hexadecimal numeric string to a number.
+** In C99, 'strtod' does that conversion. Otherwise, you can
+** leave 'lua_strx2number' undefined and Lua will provide its own
+** implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_strx2number(s,p) lua_str2number(s,p)
+#endif
+
+
+/*
+@@ lua_number2strx converts a float to an hexadecimal numeric string.
+** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
+** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
+** provide its own implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n))
+#endif
+
+
+/*
+** 'strtof' and 'opf' variants for math functions are not valid in
+** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
+** availability of these variants. ('math.h' is already included in
+** all files that use these macros.)
+*/
+#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
+#undef l_mathop /* variants not available */
+#undef lua_str2number
+#define l_mathop(op) (lua_Number)op /* no variant */
+#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
+#endif
+
+
+/*
+@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
+** functions. It must be a numerical type; Lua will use 'intptr_t' if
+** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
+** 'intptr_t' in C89)
+*/
+#define LUA_KCONTEXT ptrdiff_t
+
+#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
+ __STDC_VERSION__ >= 199901L
+#include <stdint.h>
+#if defined(INTPTR_MAX) /* even in C99 this type is optional */
+#undef LUA_KCONTEXT
+#define LUA_KCONTEXT intptr_t
+#endif
+#endif
+
+
+/*
+@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
+** Change that if you do not want to use C locales. (Code using this
+** macro must include header 'locale.h'.)
+*/
+#if !defined(lua_getlocaledecpoint)
+#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Language Variations
+** =====================================================================
+*/
+
+/*
+@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
+** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
+** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
+** coercion from strings to numbers.
+*/
+/* #define LUA_NOCVTN2S */
+/* #define LUA_NOCVTS2N */
+
+
+/*
+@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
+** Define it as a help when debugging C code.
+*/
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(l,e) assert(e)
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Macros that affect the API and must be stable (that is, must be the
+** same when you compile Lua and when you compile code that links to
+** Lua). You probably do not want/need to change them.
+** =====================================================================
+*/
+
+/*
+@@ LUAI_MAXSTACK limits the size of the Lua stack.
+** CHANGE it if you need a different limit. This limit is arbitrary;
+** its only purpose is to stop Lua from consuming unlimited stack
+** space (and to reserve some numbers for pseudo-indices).
+*/
+#if LUAI_BITSINT >= 32
+#define LUAI_MAXSTACK 1000000
+#else
+#define LUAI_MAXSTACK 15000
+#endif
+
+
+/*
+@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
+** a Lua state with very fast access.
+** CHANGE it if you need a different size.
+*/
+#define LUA_EXTRASPACE (sizeof(void *))
+
+
+/*
+@@ LUA_IDSIZE gives the maximum size for the description of the source
+@@ of a function in debug information.
+** CHANGE it if you want a different size.
+*/
+#define LUA_IDSIZE 60
+
+
+/*
+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+** CHANGE it if it uses too much C-stack space. (For long double,
+** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
+** smaller buffer would force a memory allocation for each call to
+** 'string.format'.)
+*/
+#if defined(LUA_FLOAT_LONGDOUBLE)
+#define LUAL_BUFFERSIZE 8192
+#else
+#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#endif
+
+/* }================================================================== */
+
+
+/*
+@@ LUA_QL describes how error messages quote program elements.
+** Lua does not use these macros anymore; they are here for
+** compatibility only.
+*/
+#define LUA_QL(x) "'" x "'"
+#define LUA_QS LUA_QL("%s")
+
+
+
+
+/* =================================================================== */
+
+/*
+** Local configuration. You can use this space to add your redefinitions
+** without modifying the main part of the file.
+*/
+
+
+
+
+
+#endif
+
diff --git a/project/vs2015/external/lua/include/lualib.h b/project/vs2015/external/lua/include/lualib.h
new file mode 100644
index 00000000..5165c0fb
--- /dev/null
+++ b/project/vs2015/external/lua/include/lualib.h
@@ -0,0 +1,58 @@
+/*
+** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $
+** Lua standard libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lualib_h
+#define lualib_h
+
+#include "lua.h"
+
+
+
+LUAMOD_API int (luaopen_base) (lua_State *L);
+
+#define LUA_COLIBNAME "coroutine"
+LUAMOD_API int (luaopen_coroutine) (lua_State *L);
+
+#define LUA_TABLIBNAME "table"
+LUAMOD_API int (luaopen_table) (lua_State *L);
+
+#define LUA_IOLIBNAME "io"
+LUAMOD_API int (luaopen_io) (lua_State *L);
+
+#define LUA_OSLIBNAME "os"
+LUAMOD_API int (luaopen_os) (lua_State *L);
+
+#define LUA_STRLIBNAME "string"
+LUAMOD_API int (luaopen_string) (lua_State *L);
+
+#define LUA_UTF8LIBNAME "utf8"
+LUAMOD_API int (luaopen_utf8) (lua_State *L);
+
+#define LUA_BITLIBNAME "bit32"
+LUAMOD_API int (luaopen_bit32) (lua_State *L);
+
+#define LUA_MATHLIBNAME "math"
+LUAMOD_API int (luaopen_math) (lua_State *L);
+
+#define LUA_DBLIBNAME "debug"
+LUAMOD_API int (luaopen_debug) (lua_State *L);
+
+#define LUA_LOADLIBNAME "package"
+LUAMOD_API int (luaopen_package) (lua_State *L);
+
+
+/* open all previous libraries */
+LUALIB_API void (luaL_openlibs) (lua_State *L);
+
+
+
+#if !defined(lua_assert)
+#define lua_assert(x) ((void)0)
+#endif
+
+
+#endif
diff --git a/project/vs2015/external/lua/lib/win32/lua53.dll b/project/vs2015/external/lua/lib/win32/lua53.dll
new file mode 100644
index 00000000..45300d6c
--- /dev/null
+++ b/project/vs2015/external/lua/lib/win32/lua53.dll
Binary files differ
diff --git a/project/vs2015/external/lua/lib/win32/lua53.lib b/project/vs2015/external/lua/lib/win32/lua53.lib
new file mode 100644
index 00000000..e4281777
--- /dev/null
+++ b/project/vs2015/external/lua/lib/win32/lua53.lib
Binary files differ
diff --git a/project/vs2015/external/lua/lib/win32/lua53dll.lib b/project/vs2015/external/lua/lib/win32/lua53dll.lib
new file mode 100644
index 00000000..561dc9e3
--- /dev/null
+++ b/project/vs2015/external/lua/lib/win32/lua53dll.lib
Binary files differ
diff --git a/project/vs2015/external/openal_soft/COPYING b/project/vs2015/external/openal_soft/COPYING
new file mode 100644
index 00000000..d0c89786
--- /dev/null
+++ b/project/vs2015/external/openal_soft/COPYING
@@ -0,0 +1,484 @@
+
+ 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.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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
new file mode 100644
index 00000000..413b3833
--- /dev/null
+++ b/project/vs2015/external/openal_soft/include/AL/al.h
@@ -0,0 +1,656 @@
+#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
new file mode 100644
index 00000000..294e8b33
--- /dev/null
+++ b/project/vs2015/external/openal_soft/include/AL/alc.h
@@ -0,0 +1,237 @@
+#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: <int> Hz. */
+#define ALC_FREQUENCY 0x1007
+
+/** Context attribute: <int> Hz. */
+#define ALC_REFRESH 0x1008
+
+/** Context attribute: AL_TRUE or AL_FALSE. */
+#define ALC_SYNC 0x1009
+
+/** Context attribute: <int> requested Mono (3D) Sources. */
+#define ALC_MONO_SOURCES 0x1010
+
+/** Context attribute: <int> 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
new file mode 100644
index 00000000..6af581aa
--- /dev/null
+++ b/project/vs2015/external/openal_soft/include/AL/alext.h
@@ -0,0 +1,438 @@
+/**
+ * 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 <stddef.h>
+/* Define int64_t and uint64_t types */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#include <inttypes.h>
+#elif defined(_WIN32) && defined(__GNUC__)
+#include <stdint.h>
+#elif defined(_WIN32)
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#else
+/* Fallback if nothing above works */
+#include <inttypes.h>
+#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
new file mode 100644
index 00000000..0a04c982
--- /dev/null
+++ b/project/vs2015/external/openal_soft/include/AL/efx-creative.h
@@ -0,0 +1,3 @@
+/* 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
new file mode 100644
index 00000000..8539fd51
--- /dev/null
+++ b/project/vs2015/external/openal_soft/include/AL/efx-presets.h
@@ -0,0 +1,402 @@
+/* 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
new file mode 100644
index 00000000..57766983
--- /dev/null
+++ b/project/vs2015/external/openal_soft/include/AL/efx.h
@@ -0,0 +1,761 @@
+#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
new file mode 100644
index 00000000..1e3bddd5
--- /dev/null
+++ b/project/vs2015/external/openal_soft/lib/win32/OpenAL32.dll
Binary files differ
diff --git a/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib b/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib
new file mode 100644
index 00000000..8bdca11e
--- /dev/null
+++ b/project/vs2015/external/openal_soft/lib/win32/OpenAL32.lib
Binary files differ
diff --git a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll
new file mode 100644
index 00000000..e24538a5
--- /dev/null
+++ b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.dll
Binary files differ
diff --git a/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib
new file mode 100644
index 00000000..3d6e9abf
--- /dev/null
+++ b/project/vs2015/external/openal_soft/lib/win64/OpenAL32.lib
Binary files differ
diff --git a/project/vs2015/raylib.sln b/project/vs2015/raylib.sln
new file mode 100644
index 00000000..0ac22f5e
--- /dev/null
+++ b/project/vs2015/raylib.sln
@@ -0,0 +1,40 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25123.0
+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|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {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|x86.ActiveCfg = Release|Win32
+ {0981CA98-E4A5-4DF1-987F-A41D09131EFC}.Release|x86.Build.0 = Release|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|x86.ActiveCfg = Release|Win32
+ {E89D61AC-55DE-4482-AFD4-DF7242EBC859}.Release|x86.Build.0 = Release|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|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
+EndGlobal
diff --git a/project/vs2015/raylib/ReadMe.txt b/project/vs2015/raylib/ReadMe.txt
new file mode 100644
index 00000000..0d46b9fa
--- /dev/null
+++ b/project/vs2015/raylib/ReadMe.txt
@@ -0,0 +1,29 @@
+========================================================================
+ STATIC LIBRARY : raylib Project Overview
+========================================================================
+
+AppWizard has created this raylib library project for you.
+
+No source files were created as part of your project.
+
+
+raylib.vcxproj
+ This is the main project file for VC++ projects generated using an Application Wizard.
+ It contains information about the version of Visual C++ that generated the file, and
+ information about the platforms, configurations, and project features selected with the
+ Application Wizard.
+
+raylib.vcxproj.filters
+ This is the filters file for VC++ projects generated using an Application Wizard.
+ It contains information about the association between the files in your project
+ and the filters. This association is used in the IDE to show grouping of files with
+ similar extensions under a specific node (for e.g. ".cpp" files are associated with the
+ "Source Files" filter).
+
+/////////////////////////////////////////////////////////////////////////////
+Other notes:
+
+AppWizard uses "TODO:" comments to indicate parts of the source code you
+should add to or customize.
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/project/vs2015/raylib/raylib.vcxproj b/project/vs2015/raylib/raylib.vcxproj
new file mode 100644
index 00000000..c5dd0088
--- /dev/null
+++ b/project/vs2015/raylib/raylib.vcxproj
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{E89D61AC-55DE-4482-AFD4-DF7242EBC859}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>raylib</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);GRAPHICS_API_OPENGL_33;PLATFORM_DESKTOP</PreprocessorDefinitions>
+ <CompileAs>CompileAsC</CompileAs>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\src\external\openal_soft\include;$(SolutionDir)..\..\src\external\glfw3\include;$(SolutionDir)..\..\src\external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <Lib>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Lib>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <Text Include="ReadMe.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\src\audio.c" />
+ <ClCompile Include="..\..\..\src\core.c" />
+ <ClCompile Include="..\..\..\src\external\stb_vorbis.c" />
+ <ClCompile Include="..\..\..\src\models.c" />
+ <ClCompile Include="..\..\..\src\rlgl.c" />
+ <ClCompile Include="..\..\..\src\shapes.c" />
+ <ClCompile Include="..\..\..\src\text.c" />
+ <ClCompile Include="..\..\..\src\textures.c" />
+ <ClCompile Include="..\..\..\src\utils.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\src\camera.h" />
+ <ClInclude Include="..\..\..\src\external\glad.h" />
+ <ClInclude Include="..\..\..\src\external\jar_mod.h" />
+ <ClInclude Include="..\..\..\src\external\jar_xm.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_resize.h" />
+ <ClInclude Include="..\..\..\src\external\stb_image_write.h" />
+ <ClInclude Include="..\..\..\src\external\stb_rect_pack.h" />
+ <ClInclude Include="..\..\..\src\external\stb_truetype.h" />
+ <ClInclude Include="..\..\..\src\external\stb_vorbis.h" />
+ <ClInclude Include="..\..\..\src\gestures.h" />
+ <ClInclude Include="..\..\..\src\raylib.h" />
+ <ClInclude Include="..\..\..\src\raymath.h" />
+ <ClInclude Include="..\..\..\src\rlgl.h" />
+ <ClInclude Include="..\..\..\src\shader_distortion.h" />
+ <ClInclude Include="..\..\..\src\shader_standard.h" />
+ <ClInclude Include="..\..\..\src\utils.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/release/android/raylib.h b/release/android/raylib.h
index 19c67712..fee6aa91 100644
--- a/release/android/raylib.h
+++ b/release/android/raylib.h
@@ -268,9 +268,13 @@
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
- #if !defined(_STDBOOL_H)
- typedef enum { false, true } bool;
- #define _STDBOOL_H
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
#endif
#endif
diff --git a/release/html5/libraylib.bc b/release/html5/libraylib.bc
index edf5302e..5a26136b 100644
--- a/release/html5/libraylib.bc
+++ b/release/html5/libraylib.bc
Binary files differ
diff --git a/release/html5/raylib.h b/release/html5/raylib.h
index 19c67712..fee6aa91 100644
--- a/release/html5/raylib.h
+++ b/release/html5/raylib.h
@@ -268,9 +268,13 @@
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
- #if !defined(_STDBOOL_H)
- typedef enum { false, true } bool;
- #define _STDBOOL_H
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
#endif
#endif
diff --git a/release/linux/raylib.h b/release/linux/raylib.h
index 19c67712..fee6aa91 100644
--- a/release/linux/raylib.h
+++ b/release/linux/raylib.h
@@ -268,9 +268,13 @@
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
- #if !defined(_STDBOOL_H)
- typedef enum { false, true } bool;
- #define _STDBOOL_H
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
#endif
#endif
diff --git a/release/osx/helpme! b/release/osx/helpme!
deleted file mode 100644
index e69de29b..00000000
--- a/release/osx/helpme!
+++ /dev/null
diff --git a/release/osx/libraylib.a b/release/osx/libraylib.a
new file mode 100644
index 00000000..32ca7a24
--- /dev/null
+++ b/release/osx/libraylib.a
Binary files differ
diff --git a/release/osx/raylib.h b/release/osx/raylib.h
new file mode 100644
index 00000000..fee6aa91
--- /dev/null
+++ b/release/osx/raylib.h
@@ -0,0 +1,915 @@
+/**********************************************************************************************
+*
+* raylib 1.5.0 (www.raylib.com)
+*
+* A simple and easy-to-use library to learn videogames programming
+*
+* Features:
+* Library written in plain C code (C99)
+* Uses C# PascalCase/camelCase notation
+* 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)
+* Multiple textures support, including compressed formats and mipmaps generation
+* Basic 3d support for Shapes, Models, Billboards, Heightmaps and Cubicmaps
+* Materials (diffuse, normal, specular) and Lighting (point, directional, spot) support
+* Powerful math module for Vector, Matrix and Quaternion operations [raymath]
+* Audio loading and playing with streaming support and mixing channels (WAV, OGG, XM, MOD)
+* VR stereo rendering support with configurable HMD device parameters
+* Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1
+* Custom color palette for fancy visuals on raywhite background
+* Minimal external dependencies (GLFW3, OpenGL, OpenAL)
+*
+* Used external libs:
+* GLFW3 (www.glfw.org) for window/context management and input
+* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP)
+* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
+* stb_image_write (Sean Barret) for image writting (PNG)
+* stb_vorbis (Sean Barret) for ogg audio loading
+* stb_truetype (Sean Barret) for ttf fonts loading
+* jar_xm (Joshua Reisenauer) for XM audio module loading
+* jar_mod (Joshua Reisenauer) for MOD audio module loading
+* OpenAL Soft for audio device/context management
+* tinfl for data decompression (DEFLATE algorithm)
+*
+* Some design decisions:
+* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte)
+* One custom default font is loaded automatically when InitWindow()
+* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads
+* If using OpenGL 3.3 or ES2, two default shaders are loaded automatically (internally defined)
+*
+* -- LICENSE --
+*
+* 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-2016 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)
+//#define RLGL_OCULUS_SUPPORT // Oculus Rift CV1 (complementary to PLATFORM_DESKTOP)
+
+// 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(PLATFORM_ANDROID)
+ typedef struct android_app; // Define android_app struct (android_native_app_glue.h)
+#endif
+
+//----------------------------------------------------------------------------------
+// Some basic Defines
+//----------------------------------------------------------------------------------
+#ifndef PI
+ #define PI 3.14159265358979323846
+#endif
+
+#define DEG2RAD (PI/180.0f)
+#define RAD2DEG (180.0f/PI)
+
+// raylib Config Flags
+#define FLAG_FULLSCREEN_MODE 1
+#define FLAG_SHOW_LOGO 2
+#define FLAG_SHOW_MOUSE_CURSOR 4
+#define FLAG_CENTERED_MODE 8
+#define FLAG_MSAA_4X_HINT 16
+#define FLAG_VSYNC_HINT 32
+
+// 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
+
+// Mouse Buttons
+#define MOUSE_LEFT_BUTTON 0
+#if defined(PLATFORM_WEB)
+ #define MOUSE_RIGHT_BUTTON 2
+ #define MOUSE_MIDDLE_BUTTON 1
+#else
+ #define MOUSE_RIGHT_BUTTON 1
+ #define MOUSE_MIDDLE_BUTTON 2
+#endif
+
+// Touch points registered
+#define MAX_TOUCH_POINTS 2
+
+// Gamepad Number
+#define GAMEPAD_PLAYER1 0
+#define GAMEPAD_PLAYER2 1
+#define GAMEPAD_PLAYER3 2 // Not supported
+#define GAMEPAD_PLAYER4 3 // Not supported
+
+// Gamepad Buttons
+// NOTE: Adjusted for a PS3 USB Controller
+#define GAMEPAD_BUTTON_A 2
+#define GAMEPAD_BUTTON_B 1
+#define GAMEPAD_BUTTON_X 3
+#define GAMEPAD_BUTTON_Y 4
+#define GAMEPAD_BUTTON_R1 7
+#define GAMEPAD_BUTTON_R2 5
+#define GAMEPAD_BUTTON_L1 6
+#define GAMEPAD_BUTTON_L2 8
+#define GAMEPAD_BUTTON_SELECT 9
+#define GAMEPAD_BUTTON_START 10
+
+// 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
+
+#if defined(PLATFORM_RPI)
+ #define GAMEPAD_XBOX_AXIS_DPAD_X 7
+ #define GAMEPAD_XBOX_AXIS_DPAD_Y 6
+ #define GAMEPAD_XBOX_AXIS_RIGHT_X 3
+ #define GAMEPAD_XBOX_AXIS_RIGHT_Y 4
+ #define GAMEPAD_XBOX_AXIS_LT 2
+ #define GAMEPAD_XBOX_AXIS_RT 5
+#else
+ #define GAMEPAD_XBOX_BUTTON_UP 10
+ #define GAMEPAD_XBOX_BUTTON_DOWN 12
+ #define GAMEPAD_XBOX_BUTTON_LEFT 13
+ #define GAMEPAD_XBOX_BUTTON_RIGHT 11
+ #define GAMEPAD_XBOX_AXIS_RIGHT_X 4
+ #define GAMEPAD_XBOX_AXIS_RIGHT_Y 3
+ #define GAMEPAD_XBOX_AXIS_LT_RT 2
+#endif
+
+#define GAMEPAD_XBOX_AXIS_LEFT_X 0
+#define GAMEPAD_XBOX_AXIS_LEFT_Y 1
+
+// Android Physic Buttons
+#define ANDROID_BACK 4
+#define ANDROID_MENU 82
+#define ANDROID_VOLUME_UP 24
+#define ANDROID_VOLUME_DOWN 25
+
+// Some Basic Colors
+// NOTE: Custom raylib color palette for amazing visuals on WHITE background
+#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray
+#define GRAY (Color){ 130, 130, 130, 255 } // Gray
+#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
+#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
+#define GOLD (Color){ 255, 203, 0, 255 } // Gold
+#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
+#define PINK (Color){ 255, 109, 194, 255 } // Pink
+#define RED (Color){ 230, 41, 55, 255 } // Red
+#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
+#define GREEN (Color){ 0, 228, 48, 255 } // Green
+#define LIME (Color){ 0, 158, 47, 255 } // Lime
+#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
+#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
+#define BLUE (Color){ 0, 121, 241, 255 } // Blue
+#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
+#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
+#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
+#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
+#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
+#define BROWN (Color){ 127, 106, 79, 255 } // Brown
+#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
+
+#define WHITE (Color){ 255, 255, 255, 255 } // White
+#define BLACK (Color){ 0, 0, 0, 255 } // Black
+#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
+#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
+#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+#ifndef __cplusplus
+// Boolean type
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
+ #endif
+#endif
+
+// byte type
+typedef unsigned char byte;
+
+// 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)
+} Image;
+
+// Texture2D type, bpp always RGBA (32bit)
+// 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)
+} Texture2D;
+
+// RenderTexture2D type, for texture rendering
+typedef struct RenderTexture2D {
+ unsigned int id; // Render texture (fbo) id
+ Texture2D texture; // Color buffer attachment texture
+ Texture2D depth; // Depth buffer attachment texture
+} RenderTexture2D;
+
+// SpriteFont type, includes texture and charSet array data
+typedef struct SpriteFont {
+ Texture2D texture; // Font texture
+ int size; // Base size (default chars height)
+ int numChars; // Number of characters
+ int *charValues; // Characters values array
+ Rectangle *charRecs; // Characters rectangles within the texture
+ Vector2 *charOffsets; // Characters offsets (on drawing)
+ int *charAdvanceX; // Characters x advance (on drawing)
+} 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
+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 shader)
+typedef struct Shader {
+ unsigned int id; // Shader program id
+
+ // Vertex attributes locations (default locations)
+ int vertexLoc; // Vertex attribute location point (default-location = 0)
+ int texcoordLoc; // Texcoord attribute location point (default-location = 1)
+ int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
+ int normalLoc; // Normal attribute location point (default-location = 2)
+ int tangentLoc; // Tangent attribute location point (default-location = 4)
+ int colorLoc; // Color attibute location point (default-location = 3)
+
+ // Uniform locations
+ int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
+ int tintColorLoc; // Diffuse color uniform location point (fragment shader)
+
+ // Texture map locations (generic for any kind of map)
+ int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
+ int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
+ int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
+} Shader;
+
+// Material type
+typedef struct Material {
+ Shader shader; // Standard shader (supports 3 map textures)
+
+ Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc)
+ Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
+ Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
+
+ Color colDiffuse; // Diffuse color
+ Color colAmbient; // Ambient color
+ Color colSpecular; // Specular color
+
+ float glossiness; // Glossiness level (Ranges from 0 to 1000)
+} 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;
+
+// Light type
+typedef struct LightData {
+ unsigned int id; // Light unique id
+ bool enabled; // Light enabled
+ int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
+
+ Vector3 position; // Light position
+ Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
+ float radius; // Light attenuation radius light intensity reduced with distance (world distance)
+
+ Color diffuse; // Light diffuse color
+ float intensity; // Light intensity level
+
+ float coneAngle; // Light cone max angle: LIGHT_SPOT
+} LightData, *Light;
+
+// Light types
+typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
+
+// Ray type (useful for raycast)
+typedef struct Ray {
+ Vector3 position; // Ray position (origin)
+ Vector3 direction; // Ray direction
+} Ray;
+
+// Sound source type
+typedef struct Sound {
+ unsigned int source; // Sound audio source id
+ unsigned int buffer; // Sound audio buffer id
+} Sound;
+
+// Wave type, defines audio wave data
+typedef struct Wave {
+ void *data; // Buffer data pointer
+ unsigned int dataSize; // Data size in bytes
+ unsigned int sampleRate; // Samples per second to be played
+ short bitsPerSample; // Sample size in bits
+ short channels;
+} Wave;
+
+// 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
+ 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;
+
+// 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;
+
+// Touch action (fingers or mouse)
+typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
+
+// Gesture events
+// NOTE: MAX_TOUCH_POINTS fixed to 2
+typedef struct GestureEvent {
+ int touchAction;
+ int pointCount;
+ int pointerId[MAX_TOUCH_POINTS];
+ Vector2 position[MAX_TOUCH_POINTS];
+} GestureEvent;
+
+// 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_VALVE_HTC_VIVE,
+ HMD_SAMSUNG_GEAR_VR,
+ HMD_GOOGLE_CARDBOARD,
+ HMD_SONY_PLAYSTATION_VR,
+ HMD_RAZER_OSVR,
+ HMD_FOVE_VR,
+} VrDevice;
+
+#ifdef __cplusplus
+extern "C" { // Prevents name mangling of functions
+#endif
+
+//------------------------------------------------------------------------------------
+// Global Variables Definition
+//------------------------------------------------------------------------------------
+// It's lonely here...
+
+//------------------------------------------------------------------------------------
+// Window and Graphics Device Functions (Module: core)
+//------------------------------------------------------------------------------------
+#if defined(PLATFORM_ANDROID)
+void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
+#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
+#endif
+
+void CloseWindow(void); // Close Window and Terminate Context
+bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
+bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
+void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
+int GetScreenWidth(void); // Get current screen width
+int GetScreenHeight(void); // Get current screen height
+
+void ShowCursor(void); // Shows cursor
+void HideCursor(void); // Hides cursor
+bool IsCursorHidden(void); // Returns true if cursor is not visible
+void EnableCursor(void); // Enables cursor
+void DisableCursor(void); // Disables cursor
+
+void ClearBackground(Color color); // Sets Background Color
+void BeginDrawing(void); // Setup drawing canvas to start drawing
+void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
+
+void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera
+void End2dMode(void); // Ends 2D mode custom camera usage
+void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup)
+void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
+void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
+void EndTextureMode(void); // Ends drawing to render texture
+
+Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
+Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position
+Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
+
+void SetTargetFPS(int fps); // Set target FPS (maximum)
+float GetFPS(void); // Returns current FPS
+float GetFrameTime(void); // Returns time in seconds for one frame
+
+Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+int GetHexValue(Color color); // Returns hexadecimal value for a Color
+float *ColorToFloat(Color color); // Converts Color to float array and normalizes
+float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array
+float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
+
+int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
+Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
+
+void SetConfigFlags(char flags); // Setup some window configuration flags
+void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
+
+bool IsFileDropped(void); // Check if a file have been dropped into window
+char **GetDroppedFiles(int *count); // Retrieve dropped files into window
+void ClearDroppedFiles(void); // Clear dropped files paths buffer
+
+void StorageSaveValue(int position, int value); // Storage save integer value (to defined position)
+int StorageLoadValue(int position); // Storage load integer value (from defined position)
+
+//------------------------------------------------------------------------------------
+// Input Handling Functions (Module: core)
+//------------------------------------------------------------------------------------
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+bool IsKeyPressed(int key); // Detect if a key has been pressed once
+bool IsKeyDown(int key); // Detect if a key is being pressed
+bool IsKeyReleased(int key); // Detect if a key has been released once
+bool IsKeyUp(int key); // Detect if a key is NOT being pressed
+int GetKeyPressed(void); // Get latest key pressed
+void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
+
+bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
+float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
+bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
+bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
+bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
+bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
+#endif
+
+bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
+bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
+bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
+bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
+int GetMouseX(void); // Returns mouse position X
+int GetMouseY(void); // Returns mouse position Y
+Vector2 GetMousePosition(void); // Returns mouse position XY
+void SetMousePosition(Vector2 position); // Set mouse position XY
+int GetMouseWheelMove(void); // Returns mouse wheel movement Y
+
+int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
+int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
+Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
+
+#if defined(PLATFORM_ANDROID)
+bool IsButtonPressed(int button); // Detect if an android physic button has been pressed
+bool IsButtonDown(int button); // Detect if an android physic button is being pressed
+bool IsButtonReleased(int button); // Detect if an android physic button has been released
+#endif
+
+//------------------------------------------------------------------------------------
+// Gestures and Touch Handling Functions (Module: gestures)
+//------------------------------------------------------------------------------------
+void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
+bool IsGestureDetected(int gesture); // Check if a gesture have been detected
+void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
+void UpdateGestures(void); // Update gestures detected (called automatically in PollInputEvents())
+
+int GetTouchPointsCount(void); // Get touch points count
+int GetGestureDetected(void); // Get latest detected gesture
+float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
+Vector2 GetGestureDragVector(void); // Get gesture drag vector
+float GetGestureDragAngle(void); // Get gesture drag angle
+Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
+float GetGesturePinchAngle(void); // Get gesture pinch angle
+
+//------------------------------------------------------------------------------------
+// Camera System Functions (Module: camera)
+//------------------------------------------------------------------------------------
+void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
+void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
+void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
+
+void SetCameraPosition(Vector3 position); // Set internal camera position
+void SetCameraTarget(Vector3 target); // Set internal camera target
+void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
+
+void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
+void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
+void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
+
+void SetCameraMoveControls(int frontKey, int backKey,
+ int leftKey, int rightKey,
+ int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
+void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
+
+//------------------------------------------------------------------------------------
+// Basic Shapes Drawing Functions (Module: shapes)
+//------------------------------------------------------------------------------------
+void DrawPixel(int posX, int posY, Color color); // Draw a pixel
+void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
+void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
+void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
+void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
+void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
+void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
+void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
+void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
+void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
+void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
+void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
+void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
+void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
+void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
+void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
+void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
+void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
+
+bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
+bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
+bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
+Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
+bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
+bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
+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 LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
+Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
+Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
+Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
+Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
+Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
+Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
+Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
+RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
+void UnloadImage(Image image); // Unload image from CPU memory (RAM)
+void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
+void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
+Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
+Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
+void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
+void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
+void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
+Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
+void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
+void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
+void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
+Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
+Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
+void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
+void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
+void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, int fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
+void ImageFlipVertical(Image *image); // Flip image vertically
+void ImageFlipHorizontal(Image *image); // Flip image horizontally
+void ImageColorTint(Image *image, Color color); // Modify image color: tint
+void ImageColorInvert(Image *image); // Modify image color: invert
+void ImageColorGrayscale(Image *image); // Modify image color: grayscale
+void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
+void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
+void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
+void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
+
+void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
+void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
+void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
+void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
+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 GetDefaultFont(void); // Get the default SpriteFont
+SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
+void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
+
+void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
+void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
+ int fontSize, int spacing, Color tint);
+int MeasureText(const char *text, int fontSize); // Measure string width for default font
+Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
+
+void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
+const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
+const char *SubText(const char *text, int position, int length); // Get a piece of a text string
+
+//------------------------------------------------------------------------------------
+// Basic 3d Shapes Drawing Functions (Module: models)
+//------------------------------------------------------------------------------------
+void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
+void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
+void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
+void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
+void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
+void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
+void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
+void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
+void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
+void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
+void DrawRay(Ray ray, Color color); // Draw a ray line
+void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
+void DrawGizmo(Vector3 position); // Draw simple gizmo
+void DrawLight(Light light); // Draw light in 3D world
+void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
+void Draw3DCircle(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color); // Draw a circle in 3D world space
+//DrawTorus(), DrawTeapot() are useless...
+
+//------------------------------------------------------------------------------------
+// Model 3d Loading and Drawing Functions (Module: models)
+//------------------------------------------------------------------------------------
+Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
+Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
+Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
+Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
+Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
+void UnloadModel(Model model); // Unload 3d model from memory
+
+Material LoadMaterial(const char *fileName); // Load material data (from file)
+Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
+Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader)
+void UnloadMaterial(Material material); // Unload material textures from VRAM
+
+void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
+void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
+void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
+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
+void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
+
+void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
+void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
+
+BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
+bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
+bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
+bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
+bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
+bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection
+bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
+Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap
+ // NOTE: Return the normal vector of the impacted surface
+//------------------------------------------------------------------------------------
+// Shaders System Functions (Module: rlgl)
+// NOTE: This functions are useless when using OpenGL 1.1
+//------------------------------------------------------------------------------------
+Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
+void UnloadShader(Shader shader); // Unload a custom shader from memory
+
+Shader GetDefaultShader(void); // Get default shader
+Shader GetStandardShader(void); // Get standard shader
+Texture2D GetDefaultTexture(void); // Get default texture
+
+int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
+void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
+void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
+void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
+
+void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
+void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
+
+void BeginShaderMode(Shader shader); // Begin custom shader drawing
+void EndShaderMode(void); // End custom shader drawing (use default shader)
+void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
+void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
+
+Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
+void DestroyLight(Light light); // Destroy a light and take it out of the list
+
+//------------------------------------------------------------------------------------
+// VR experience Functions (Module: rlgl)
+// NOTE: This functions are useless when using OpenGL 1.1
+//------------------------------------------------------------------------------------
+void InitVrDevice(int vdDevice); // Init VR device
+void CloseVrDevice(void); // Close VR device
+void UpdateVrTracking(void); // Update VR tracking (position and orientation)
+void BeginVrDrawing(void); // Begin VR drawing configuration
+void EndVrDrawing(void); // End VR drawing process (and desktop mirror)
+bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
+void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
+
+//------------------------------------------------------------------------------------
+// Audio Loading and Playing Functions (Module: audio)
+//------------------------------------------------------------------------------------
+void InitAudioDevice(void); // Initialize audio device and context
+void CloseAudioDevice(void); // Close the audio device and context (and music stream)
+bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet
+
+Sound LoadSound(char *fileName); // Load sound to memory
+Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
+Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
+void UnloadSound(Sound sound); // Unload sound
+void PlaySound(Sound sound); // Play a sound
+void PauseSound(Sound sound); // Pause a sound
+void StopSound(Sound sound); // Stop playing a sound
+bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
+void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
+void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
+
+int PlayMusicStream(int index, char *fileName); // Start music playing (open stream)
+void UpdateMusicStream(int index); // Updates buffers for music streaming
+void StopMusicStream(int index); // Stop music playing (close stream)
+void PauseMusicStream(int index); // Pause music playing
+void ResumeMusicStream(int index); // Resume playing paused music
+bool IsMusicPlaying(int index); // Check if music is playing
+void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
+void SetMusicPitch(int index, float pitch); // Set pitch for a music (1.0 is base level)
+float GetMusicTimeLength(int index); // Get current music time length (in seconds)
+float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
+int GetMusicStreamCount(void); // Get number of streams loaded
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // RAYLIB_H
diff --git a/release/rpi/libraylib.a b/release/rpi/libraylib.a
new file mode 100644
index 00000000..522e02bd
--- /dev/null
+++ b/release/rpi/libraylib.a
Binary files differ
diff --git a/release/rpi/raylib.h b/release/rpi/raylib.h
new file mode 100644
index 00000000..fee6aa91
--- /dev/null
+++ b/release/rpi/raylib.h
@@ -0,0 +1,915 @@
+/**********************************************************************************************
+*
+* raylib 1.5.0 (www.raylib.com)
+*
+* A simple and easy-to-use library to learn videogames programming
+*
+* Features:
+* Library written in plain C code (C99)
+* Uses C# PascalCase/camelCase notation
+* 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)
+* Multiple textures support, including compressed formats and mipmaps generation
+* Basic 3d support for Shapes, Models, Billboards, Heightmaps and Cubicmaps
+* Materials (diffuse, normal, specular) and Lighting (point, directional, spot) support
+* Powerful math module for Vector, Matrix and Quaternion operations [raymath]
+* Audio loading and playing with streaming support and mixing channels (WAV, OGG, XM, MOD)
+* VR stereo rendering support with configurable HMD device parameters
+* Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1
+* Custom color palette for fancy visuals on raywhite background
+* Minimal external dependencies (GLFW3, OpenGL, OpenAL)
+*
+* Used external libs:
+* GLFW3 (www.glfw.org) for window/context management and input
+* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP)
+* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
+* stb_image_write (Sean Barret) for image writting (PNG)
+* stb_vorbis (Sean Barret) for ogg audio loading
+* stb_truetype (Sean Barret) for ttf fonts loading
+* jar_xm (Joshua Reisenauer) for XM audio module loading
+* jar_mod (Joshua Reisenauer) for MOD audio module loading
+* OpenAL Soft for audio device/context management
+* tinfl for data decompression (DEFLATE algorithm)
+*
+* Some design decisions:
+* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte)
+* One custom default font is loaded automatically when InitWindow()
+* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads
+* If using OpenGL 3.3 or ES2, two default shaders are loaded automatically (internally defined)
+*
+* -- LICENSE --
+*
+* 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-2016 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)
+//#define RLGL_OCULUS_SUPPORT // Oculus Rift CV1 (complementary to PLATFORM_DESKTOP)
+
+// 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(PLATFORM_ANDROID)
+ typedef struct android_app; // Define android_app struct (android_native_app_glue.h)
+#endif
+
+//----------------------------------------------------------------------------------
+// Some basic Defines
+//----------------------------------------------------------------------------------
+#ifndef PI
+ #define PI 3.14159265358979323846
+#endif
+
+#define DEG2RAD (PI/180.0f)
+#define RAD2DEG (180.0f/PI)
+
+// raylib Config Flags
+#define FLAG_FULLSCREEN_MODE 1
+#define FLAG_SHOW_LOGO 2
+#define FLAG_SHOW_MOUSE_CURSOR 4
+#define FLAG_CENTERED_MODE 8
+#define FLAG_MSAA_4X_HINT 16
+#define FLAG_VSYNC_HINT 32
+
+// 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
+
+// Mouse Buttons
+#define MOUSE_LEFT_BUTTON 0
+#if defined(PLATFORM_WEB)
+ #define MOUSE_RIGHT_BUTTON 2
+ #define MOUSE_MIDDLE_BUTTON 1
+#else
+ #define MOUSE_RIGHT_BUTTON 1
+ #define MOUSE_MIDDLE_BUTTON 2
+#endif
+
+// Touch points registered
+#define MAX_TOUCH_POINTS 2
+
+// Gamepad Number
+#define GAMEPAD_PLAYER1 0
+#define GAMEPAD_PLAYER2 1
+#define GAMEPAD_PLAYER3 2 // Not supported
+#define GAMEPAD_PLAYER4 3 // Not supported
+
+// Gamepad Buttons
+// NOTE: Adjusted for a PS3 USB Controller
+#define GAMEPAD_BUTTON_A 2
+#define GAMEPAD_BUTTON_B 1
+#define GAMEPAD_BUTTON_X 3
+#define GAMEPAD_BUTTON_Y 4
+#define GAMEPAD_BUTTON_R1 7
+#define GAMEPAD_BUTTON_R2 5
+#define GAMEPAD_BUTTON_L1 6
+#define GAMEPAD_BUTTON_L2 8
+#define GAMEPAD_BUTTON_SELECT 9
+#define GAMEPAD_BUTTON_START 10
+
+// 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
+
+#if defined(PLATFORM_RPI)
+ #define GAMEPAD_XBOX_AXIS_DPAD_X 7
+ #define GAMEPAD_XBOX_AXIS_DPAD_Y 6
+ #define GAMEPAD_XBOX_AXIS_RIGHT_X 3
+ #define GAMEPAD_XBOX_AXIS_RIGHT_Y 4
+ #define GAMEPAD_XBOX_AXIS_LT 2
+ #define GAMEPAD_XBOX_AXIS_RT 5
+#else
+ #define GAMEPAD_XBOX_BUTTON_UP 10
+ #define GAMEPAD_XBOX_BUTTON_DOWN 12
+ #define GAMEPAD_XBOX_BUTTON_LEFT 13
+ #define GAMEPAD_XBOX_BUTTON_RIGHT 11
+ #define GAMEPAD_XBOX_AXIS_RIGHT_X 4
+ #define GAMEPAD_XBOX_AXIS_RIGHT_Y 3
+ #define GAMEPAD_XBOX_AXIS_LT_RT 2
+#endif
+
+#define GAMEPAD_XBOX_AXIS_LEFT_X 0
+#define GAMEPAD_XBOX_AXIS_LEFT_Y 1
+
+// Android Physic Buttons
+#define ANDROID_BACK 4
+#define ANDROID_MENU 82
+#define ANDROID_VOLUME_UP 24
+#define ANDROID_VOLUME_DOWN 25
+
+// Some Basic Colors
+// NOTE: Custom raylib color palette for amazing visuals on WHITE background
+#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray
+#define GRAY (Color){ 130, 130, 130, 255 } // Gray
+#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
+#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
+#define GOLD (Color){ 255, 203, 0, 255 } // Gold
+#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
+#define PINK (Color){ 255, 109, 194, 255 } // Pink
+#define RED (Color){ 230, 41, 55, 255 } // Red
+#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
+#define GREEN (Color){ 0, 228, 48, 255 } // Green
+#define LIME (Color){ 0, 158, 47, 255 } // Lime
+#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
+#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
+#define BLUE (Color){ 0, 121, 241, 255 } // Blue
+#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
+#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
+#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
+#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
+#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
+#define BROWN (Color){ 127, 106, 79, 255 } // Brown
+#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
+
+#define WHITE (Color){ 255, 255, 255, 255 } // White
+#define BLACK (Color){ 0, 0, 0, 255 } // Black
+#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
+#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
+#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+#ifndef __cplusplus
+// Boolean type
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
+ #endif
+#endif
+
+// byte type
+typedef unsigned char byte;
+
+// 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)
+} Image;
+
+// Texture2D type, bpp always RGBA (32bit)
+// 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)
+} Texture2D;
+
+// RenderTexture2D type, for texture rendering
+typedef struct RenderTexture2D {
+ unsigned int id; // Render texture (fbo) id
+ Texture2D texture; // Color buffer attachment texture
+ Texture2D depth; // Depth buffer attachment texture
+} RenderTexture2D;
+
+// SpriteFont type, includes texture and charSet array data
+typedef struct SpriteFont {
+ Texture2D texture; // Font texture
+ int size; // Base size (default chars height)
+ int numChars; // Number of characters
+ int *charValues; // Characters values array
+ Rectangle *charRecs; // Characters rectangles within the texture
+ Vector2 *charOffsets; // Characters offsets (on drawing)
+ int *charAdvanceX; // Characters x advance (on drawing)
+} 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
+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 shader)
+typedef struct Shader {
+ unsigned int id; // Shader program id
+
+ // Vertex attributes locations (default locations)
+ int vertexLoc; // Vertex attribute location point (default-location = 0)
+ int texcoordLoc; // Texcoord attribute location point (default-location = 1)
+ int texcoord2Loc; // Texcoord2 attribute location point (default-location = 5)
+ int normalLoc; // Normal attribute location point (default-location = 2)
+ int tangentLoc; // Tangent attribute location point (default-location = 4)
+ int colorLoc; // Color attibute location point (default-location = 3)
+
+ // Uniform locations
+ int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
+ int tintColorLoc; // Diffuse color uniform location point (fragment shader)
+
+ // Texture map locations (generic for any kind of map)
+ int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
+ int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
+ int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
+} Shader;
+
+// Material type
+typedef struct Material {
+ Shader shader; // Standard shader (supports 3 map textures)
+
+ Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc)
+ Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
+ Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
+
+ Color colDiffuse; // Diffuse color
+ Color colAmbient; // Ambient color
+ Color colSpecular; // Specular color
+
+ float glossiness; // Glossiness level (Ranges from 0 to 1000)
+} 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;
+
+// Light type
+typedef struct LightData {
+ unsigned int id; // Light unique id
+ bool enabled; // Light enabled
+ int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
+
+ Vector3 position; // Light position
+ Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
+ float radius; // Light attenuation radius light intensity reduced with distance (world distance)
+
+ Color diffuse; // Light diffuse color
+ float intensity; // Light intensity level
+
+ float coneAngle; // Light cone max angle: LIGHT_SPOT
+} LightData, *Light;
+
+// Light types
+typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
+
+// Ray type (useful for raycast)
+typedef struct Ray {
+ Vector3 position; // Ray position (origin)
+ Vector3 direction; // Ray direction
+} Ray;
+
+// Sound source type
+typedef struct Sound {
+ unsigned int source; // Sound audio source id
+ unsigned int buffer; // Sound audio buffer id
+} Sound;
+
+// Wave type, defines audio wave data
+typedef struct Wave {
+ void *data; // Buffer data pointer
+ unsigned int dataSize; // Data size in bytes
+ unsigned int sampleRate; // Samples per second to be played
+ short bitsPerSample; // Sample size in bits
+ short channels;
+} Wave;
+
+// 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
+ 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;
+
+// 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;
+
+// Touch action (fingers or mouse)
+typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
+
+// Gesture events
+// NOTE: MAX_TOUCH_POINTS fixed to 2
+typedef struct GestureEvent {
+ int touchAction;
+ int pointCount;
+ int pointerId[MAX_TOUCH_POINTS];
+ Vector2 position[MAX_TOUCH_POINTS];
+} GestureEvent;
+
+// 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_VALVE_HTC_VIVE,
+ HMD_SAMSUNG_GEAR_VR,
+ HMD_GOOGLE_CARDBOARD,
+ HMD_SONY_PLAYSTATION_VR,
+ HMD_RAZER_OSVR,
+ HMD_FOVE_VR,
+} VrDevice;
+
+#ifdef __cplusplus
+extern "C" { // Prevents name mangling of functions
+#endif
+
+//------------------------------------------------------------------------------------
+// Global Variables Definition
+//------------------------------------------------------------------------------------
+// It's lonely here...
+
+//------------------------------------------------------------------------------------
+// Window and Graphics Device Functions (Module: core)
+//------------------------------------------------------------------------------------
+#if defined(PLATFORM_ANDROID)
+void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
+#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
+#endif
+
+void CloseWindow(void); // Close Window and Terminate Context
+bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
+bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
+void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
+int GetScreenWidth(void); // Get current screen width
+int GetScreenHeight(void); // Get current screen height
+
+void ShowCursor(void); // Shows cursor
+void HideCursor(void); // Hides cursor
+bool IsCursorHidden(void); // Returns true if cursor is not visible
+void EnableCursor(void); // Enables cursor
+void DisableCursor(void); // Disables cursor
+
+void ClearBackground(Color color); // Sets Background Color
+void BeginDrawing(void); // Setup drawing canvas to start drawing
+void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
+
+void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera
+void End2dMode(void); // Ends 2D mode custom camera usage
+void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup)
+void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
+void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
+void EndTextureMode(void); // Ends drawing to render texture
+
+Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
+Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position
+Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
+
+void SetTargetFPS(int fps); // Set target FPS (maximum)
+float GetFPS(void); // Returns current FPS
+float GetFrameTime(void); // Returns time in seconds for one frame
+
+Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+int GetHexValue(Color color); // Returns hexadecimal value for a Color
+float *ColorToFloat(Color color); // Converts Color to float array and normalizes
+float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array
+float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
+
+int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
+Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
+
+void SetConfigFlags(char flags); // Setup some window configuration flags
+void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
+
+bool IsFileDropped(void); // Check if a file have been dropped into window
+char **GetDroppedFiles(int *count); // Retrieve dropped files into window
+void ClearDroppedFiles(void); // Clear dropped files paths buffer
+
+void StorageSaveValue(int position, int value); // Storage save integer value (to defined position)
+int StorageLoadValue(int position); // Storage load integer value (from defined position)
+
+//------------------------------------------------------------------------------------
+// Input Handling Functions (Module: core)
+//------------------------------------------------------------------------------------
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+bool IsKeyPressed(int key); // Detect if a key has been pressed once
+bool IsKeyDown(int key); // Detect if a key is being pressed
+bool IsKeyReleased(int key); // Detect if a key has been released once
+bool IsKeyUp(int key); // Detect if a key is NOT being pressed
+int GetKeyPressed(void); // Get latest key pressed
+void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
+
+bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
+float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
+bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
+bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
+bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
+bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
+#endif
+
+bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
+bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
+bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
+bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
+int GetMouseX(void); // Returns mouse position X
+int GetMouseY(void); // Returns mouse position Y
+Vector2 GetMousePosition(void); // Returns mouse position XY
+void SetMousePosition(Vector2 position); // Set mouse position XY
+int GetMouseWheelMove(void); // Returns mouse wheel movement Y
+
+int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
+int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
+Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
+
+#if defined(PLATFORM_ANDROID)
+bool IsButtonPressed(int button); // Detect if an android physic button has been pressed
+bool IsButtonDown(int button); // Detect if an android physic button is being pressed
+bool IsButtonReleased(int button); // Detect if an android physic button has been released
+#endif
+
+//------------------------------------------------------------------------------------
+// Gestures and Touch Handling Functions (Module: gestures)
+//------------------------------------------------------------------------------------
+void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
+bool IsGestureDetected(int gesture); // Check if a gesture have been detected
+void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
+void UpdateGestures(void); // Update gestures detected (called automatically in PollInputEvents())
+
+int GetTouchPointsCount(void); // Get touch points count
+int GetGestureDetected(void); // Get latest detected gesture
+float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
+Vector2 GetGestureDragVector(void); // Get gesture drag vector
+float GetGestureDragAngle(void); // Get gesture drag angle
+Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
+float GetGesturePinchAngle(void); // Get gesture pinch angle
+
+//------------------------------------------------------------------------------------
+// Camera System Functions (Module: camera)
+//------------------------------------------------------------------------------------
+void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
+void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
+void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
+
+void SetCameraPosition(Vector3 position); // Set internal camera position
+void SetCameraTarget(Vector3 target); // Set internal camera target
+void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
+
+void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
+void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
+void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
+
+void SetCameraMoveControls(int frontKey, int backKey,
+ int leftKey, int rightKey,
+ int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
+void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
+
+//------------------------------------------------------------------------------------
+// Basic Shapes Drawing Functions (Module: shapes)
+//------------------------------------------------------------------------------------
+void DrawPixel(int posX, int posY, Color color); // Draw a pixel
+void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
+void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
+void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
+void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
+void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
+void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
+void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
+void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
+void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
+void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
+void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
+void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
+void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
+void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
+void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
+void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
+void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
+
+bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
+bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
+bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
+Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
+bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
+bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
+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 LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
+Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
+Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
+Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
+Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
+Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
+Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
+Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
+RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
+void UnloadImage(Image image); // Unload image from CPU memory (RAM)
+void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
+void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
+Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
+Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
+void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
+void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
+void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
+Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
+void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
+void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
+void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
+Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
+Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
+void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
+void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
+void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, int fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
+void ImageFlipVertical(Image *image); // Flip image vertically
+void ImageFlipHorizontal(Image *image); // Flip image horizontally
+void ImageColorTint(Image *image, Color color); // Modify image color: tint
+void ImageColorInvert(Image *image); // Modify image color: invert
+void ImageColorGrayscale(Image *image); // Modify image color: grayscale
+void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
+void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
+void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
+void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
+
+void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
+void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
+void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
+void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
+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 GetDefaultFont(void); // Get the default SpriteFont
+SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
+void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
+
+void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
+void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
+ int fontSize, int spacing, Color tint);
+int MeasureText(const char *text, int fontSize); // Measure string width for default font
+Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
+
+void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
+const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
+const char *SubText(const char *text, int position, int length); // Get a piece of a text string
+
+//------------------------------------------------------------------------------------
+// Basic 3d Shapes Drawing Functions (Module: models)
+//------------------------------------------------------------------------------------
+void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
+void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
+void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
+void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
+void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
+void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
+void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
+void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
+void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
+void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
+void DrawRay(Ray ray, Color color); // Draw a ray line
+void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
+void DrawGizmo(Vector3 position); // Draw simple gizmo
+void DrawLight(Light light); // Draw light in 3D world
+void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
+void Draw3DCircle(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color); // Draw a circle in 3D world space
+//DrawTorus(), DrawTeapot() are useless...
+
+//------------------------------------------------------------------------------------
+// Model 3d Loading and Drawing Functions (Module: models)
+//------------------------------------------------------------------------------------
+Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
+Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
+Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
+Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
+Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
+void UnloadModel(Model model); // Unload 3d model from memory
+
+Material LoadMaterial(const char *fileName); // Load material data (from file)
+Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
+Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader)
+void UnloadMaterial(Material material); // Unload material textures from VRAM
+
+void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
+void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
+void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
+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
+void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
+
+void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
+void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
+
+BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
+bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
+bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
+bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
+bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
+bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection
+bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
+Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap
+ // NOTE: Return the normal vector of the impacted surface
+//------------------------------------------------------------------------------------
+// Shaders System Functions (Module: rlgl)
+// NOTE: This functions are useless when using OpenGL 1.1
+//------------------------------------------------------------------------------------
+Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
+void UnloadShader(Shader shader); // Unload a custom shader from memory
+
+Shader GetDefaultShader(void); // Get default shader
+Shader GetStandardShader(void); // Get standard shader
+Texture2D GetDefaultTexture(void); // Get default texture
+
+int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
+void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
+void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
+void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
+
+void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
+void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
+
+void BeginShaderMode(Shader shader); // Begin custom shader drawing
+void EndShaderMode(void); // End custom shader drawing (use default shader)
+void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
+void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
+
+Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
+void DestroyLight(Light light); // Destroy a light and take it out of the list
+
+//------------------------------------------------------------------------------------
+// VR experience Functions (Module: rlgl)
+// NOTE: This functions are useless when using OpenGL 1.1
+//------------------------------------------------------------------------------------
+void InitVrDevice(int vdDevice); // Init VR device
+void CloseVrDevice(void); // Close VR device
+void UpdateVrTracking(void); // Update VR tracking (position and orientation)
+void BeginVrDrawing(void); // Begin VR drawing configuration
+void EndVrDrawing(void); // End VR drawing process (and desktop mirror)
+bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
+void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
+
+//------------------------------------------------------------------------------------
+// Audio Loading and Playing Functions (Module: audio)
+//------------------------------------------------------------------------------------
+void InitAudioDevice(void); // Initialize audio device and context
+void CloseAudioDevice(void); // Close the audio device and context (and music stream)
+bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet
+
+Sound LoadSound(char *fileName); // Load sound to memory
+Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
+Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
+void UnloadSound(Sound sound); // Unload sound
+void PlaySound(Sound sound); // Play a sound
+void PauseSound(Sound sound); // Pause a sound
+void StopSound(Sound sound); // Stop playing a sound
+bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
+void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
+void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
+
+int PlayMusicStream(int index, char *fileName); // Start music playing (open stream)
+void UpdateMusicStream(int index); // Updates buffers for music streaming
+void StopMusicStream(int index); // Stop music playing (close stream)
+void PauseMusicStream(int index); // Pause music playing
+void ResumeMusicStream(int index); // Resume playing paused music
+bool IsMusicPlaying(int index); // Check if music is playing
+void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
+void SetMusicPitch(int index, float pitch); // Set pitch for a music (1.0 is base level)
+float GetMusicTimeLength(int index); // Get current music time length (in seconds)
+float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
+int GetMusicStreamCount(void); // Get number of streams loaded
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // RAYLIB_H
diff --git a/release/win32/mingw32/libraylib.a b/release/win32/mingw32/libraylib.a
index abb8ddd1..6e9db0d2 100644
--- a/release/win32/mingw32/libraylib.a
+++ b/release/win32/mingw32/libraylib.a
Binary files differ
diff --git a/release/win32/raylib.h b/release/win32/raylib.h
index 19c67712..fee6aa91 100644
--- a/release/win32/raylib.h
+++ b/release/win32/raylib.h
@@ -268,9 +268,13 @@
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
- #if !defined(_STDBOOL_H)
- typedef enum { false, true } bool;
- #define _STDBOOL_H
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
#endif
#endif
diff --git a/shaders/glsl100/bloom.fs b/shaders/glsl100/bloom.fs
index 128736f2..a8e1d20f 100644
--- a/shaders/glsl100/bloom.fs
+++ b/shaders/glsl100/bloom.fs
@@ -8,30 +8,32 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+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);
- vec4 tc = vec4(0);
+ vec2 sizeFactor = vec2(1)/size*quality;
+
+ // Texel color fetching from texture sampler
+ vec4 source = texture2D(texture0, fragTexCoord);
- for (int i = -4; i < 4; i++)
+ const int range = 2; // should be = (samples - 1)/2;
+
+ for (int x = -range; x <= range; x++)
{
- for (int j = -3; j < 3; j++)
+ for (int y = -range; y <= range; y++)
{
- sum += texture2D(texture0, fragTexCoord + vec2(j, i)*0.004) * 0.25;
+ sum += texture2D(texture0, fragTexCoord + vec2(x, y)*sizeFactor);
}
}
-
- // Texel color fetching from texture sampler
- vec4 texelColor = texture2D(texture0, fragTexCoord);
-
+
// Calculate final fragment color
- if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
- else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
- else tc = sum*sum*0.0075 + texelColor;
-
- gl_FragColor = tc;
+ gl_FragColor = ((sum/(samples*samples)) + source)*colDiffuse;
} \ No newline at end of file
diff --git a/shaders/glsl100/blur.fs b/shaders/glsl100/blur.fs
index 80d40834..1935f080 100644
--- a/shaders/glsl100/blur.fs
+++ b/shaders/glsl100/blur.fs
@@ -8,12 +8,13 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
-const float renderWidth = 1280;
-const float renderHeight = 720;
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
float offset[3] = float[]( 0.0, 1.3846153846, 3.2307692308 );
float weight[3] = float[]( 0.2270270270, 0.3162162162, 0.0702702703 );
diff --git a/shaders/glsl100/cross_hatching.fs b/shaders/glsl100/cross_hatching.fs
index 1f7dab08..ced0fd63 100644
--- a/shaders/glsl100/cross_hatching.fs
+++ b/shaders/glsl100/cross_hatching.fs
@@ -8,7 +8,7 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl100/cross_stitching.fs b/shaders/glsl100/cross_stitching.fs
index 6fabc027..67639a55 100644
--- a/shaders/glsl100/cross_stitching.fs
+++ b/shaders/glsl100/cross_stitching.fs
@@ -8,12 +8,13 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
-const float renderWidth = 1280;
-const float renderHeight = 720;
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
float stitchingSize = 6.0f;
diff --git a/shaders/glsl100/dream_vision.fs b/shaders/glsl100/dream_vision.fs
index d0cdc687..fa9c5b77 100644
--- a/shaders/glsl100/dream_vision.fs
+++ b/shaders/glsl100/dream_vision.fs
@@ -8,7 +8,7 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl100/fisheye.fs b/shaders/glsl100/fisheye.fs
index 9dba297b..461e1405 100644
--- a/shaders/glsl100/fisheye.fs
+++ b/shaders/glsl100/fisheye.fs
@@ -8,7 +8,7 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl100/pixel.fs b/shaders/glsl100/pixel.fs
index c532f219..41ba3ed6 100644
--- a/shaders/glsl100/pixel.fs
+++ b/shaders/glsl100/pixel.fs
@@ -8,12 +8,13 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
-const float renderWidth = 1280;
-const float renderHeight = 720;
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
uniform float pixelWidth = 5.0f;
uniform float pixelHeight = 5.0f;
diff --git a/shaders/glsl100/posterization.fs b/shaders/glsl100/posterization.fs
index 801ca89c..a7942c82 100644
--- a/shaders/glsl100/posterization.fs
+++ b/shaders/glsl100/posterization.fs
@@ -8,7 +8,7 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl100/predator.fs b/shaders/glsl100/predator.fs
index 1f0e2ce5..efa7fe79 100644
--- a/shaders/glsl100/predator.fs
+++ b/shaders/glsl100/predator.fs
@@ -8,7 +8,7 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl100/scanlines.fs b/shaders/glsl100/scanlines.fs
index d885e10b..529120d0 100644
--- a/shaders/glsl100/scanlines.fs
+++ b/shaders/glsl100/scanlines.fs
@@ -8,7 +8,7 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl100/standard.fs b/shaders/glsl100/standard.fs
index d5daa445..3e78022d 100644
--- a/shaders/glsl100/standard.fs
+++ b/shaders/glsl100/standard.fs
@@ -34,7 +34,6 @@ struct Light {
};
const int maxLights = 8;
-uniform int lightsCount;
uniform Light lights[maxLights];
vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s)
@@ -134,19 +133,15 @@ void main()
float spec = 1.0;
if (useSpecular == 1) spec *= normalize(texture2D(texture2, fragTexCoord).r);
- for (int i = 0; i < lightsCount; i++)
+ for (int i = 0; i < maxLights; i++)
{
// Check if light is enabled
if (lights[i].enabled == 1)
{
// Calculate lighting based on light type
- switch (lights[i].type)
- {
- case 0: lighting += CalcPointLight(lights[i], n, v, spec); break;
- case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break;
- case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break;
- default: break;
- }
+ if(lights[i].type == 0) lighting += CalcPointLight(lights[i], n, v, spec);
+ else if(lights[i].type == 1) lighting += CalcDirectionalLight(lights[i], n, v, spec);
+ else if(lights[i].type == 2) lighting += CalcSpotLight(lights[i], n, v, spec);
}
}
diff --git a/shaders/glsl100/swirl.fs b/shaders/glsl100/swirl.fs
index 0d6d24f2..6b17874c 100644
--- a/shaders/glsl100/swirl.fs
+++ b/shaders/glsl100/swirl.fs
@@ -8,12 +8,13 @@ varying vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
-const float renderWidth = 800.0; // HARDCODED for example!
-const float renderHeight = 480.0; // Use uniforms instead...
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
float radius = 250.0;
float angle = 0.8;
diff --git a/shaders/glsl330/bloom.fs b/shaders/glsl330/bloom.fs
index 0307bc06..333d5b05 100644
--- a/shaders/glsl330/bloom.fs
+++ b/shaders/glsl330/bloom.fs
@@ -6,33 +6,35 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// 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);
- vec4 tc = vec4(0);
+ vec2 sizeFactor = vec2(1)/size*quality;
+
+ // Texel color fetching from texture sampler
+ vec4 source = texture(texture0, fragTexCoord);
+
+ const int range = 2; // should be = (samples - 1)/2;
- for (int i = -4; i < 4; i++)
+ for (int x = -range; x <= range; x++)
{
- for (int j = -3; j < 3; j++)
+ for (int y = -range; y <= range; y++)
{
- sum += texture(texture0, fragTexCoord + vec2(j, i)*0.004)*0.25;
+ sum += texture(texture0, fragTexCoord + vec2(x, y)*sizeFactor);
}
}
-
- // Texel color fetching from texture sampler
- vec4 texelColor = texture(texture0, fragTexCoord);
-
- // Calculate final fragment color
- if (texelColor.r < 0.3) tc = sum*sum*0.012 + texelColor;
- else if (texelColor.r < 0.5) tc = sum*sum*0.009 + texelColor;
- else tc = sum*sum*0.0075 + texelColor;
- finalColor = tc;
+ // Calculate final fragment color
+ finalColor = ((sum/(samples*samples)) + source)*colDiffuse;
} \ No newline at end of file
diff --git a/shaders/glsl330/blur.fs b/shaders/glsl330/blur.fs
index 7c31f727..e4df406d 100644
--- a/shaders/glsl330/blur.fs
+++ b/shaders/glsl330/blur.fs
@@ -6,15 +6,16 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
-const float renderWidth = 1280.0;
-const float renderHeight = 720.0;
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
float offset[3] = float[](0.0, 1.3846153846, 3.2307692308);
float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703);
diff --git a/shaders/glsl330/cross_hatching.fs b/shaders/glsl330/cross_hatching.fs
index c12c48cd..f95ad075 100644
--- a/shaders/glsl330/cross_hatching.fs
+++ b/shaders/glsl330/cross_hatching.fs
@@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
diff --git a/shaders/glsl330/cross_stitching.fs b/shaders/glsl330/cross_stitching.fs
index 7c87c6cd..9cdd36ca 100644
--- a/shaders/glsl330/cross_stitching.fs
+++ b/shaders/glsl330/cross_stitching.fs
@@ -6,15 +6,16 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
-const float renderWidth = 1280.0;
-const float renderHeight = 720.0;
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800.0;
+const float renderHeight = 450.0;
float stitchingSize = 6.0;
diff --git a/shaders/glsl330/depth.fs b/shaders/glsl330/depth.fs
index 06d399f9..2422f390 100644
--- a/shaders/glsl330/depth.fs
+++ b/shaders/glsl330/depth.fs
@@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0; // Depth texture
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
diff --git a/shaders/glsl330/dream_vision.fs b/shaders/glsl330/dream_vision.fs
index 0ea4ce20..03115862 100644
--- a/shaders/glsl330/dream_vision.fs
+++ b/shaders/glsl330/dream_vision.fs
@@ -5,7 +5,7 @@ in vec2 fragTexCoord;
out vec4 fragColor;
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl330/fisheye.fs b/shaders/glsl330/fisheye.fs
index 5bd9abf4..e85d7c9d 100644
--- a/shaders/glsl330/fisheye.fs
+++ b/shaders/glsl330/fisheye.fs
@@ -5,7 +5,7 @@ in vec2 fragTexCoord;
out vec4 fragColor;
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
diff --git a/shaders/glsl330/phong.fs b/shaders/glsl330/phong.fs
deleted file mode 100644
index b2414a15..00000000
--- a/shaders/glsl330/phong.fs
+++ /dev/null
@@ -1,85 +0,0 @@
-#version 330
-
-// Input vertex attributes (from vertex shader)
-in vec2 fragTexCoord;
-in vec3 fragNormal;
-
-// Input uniform values
-uniform sampler2D texture0;
-uniform vec4 colDiffuse;
-
-// Output fragment color
-out vec4 finalColor;
-
-// NOTE: Add here your custom variables
-
-// Light uniform values
-uniform vec3 lightAmbientColor = vec3(0.6, 0.3, 0.0);
-uniform vec3 lightDiffuseColor = vec3(1.0, 0.5, 0.0);
-uniform vec3 lightSpecularColor = vec3(0.0, 1.0, 0.0);
-uniform float lightIntensity = 1.0;
-uniform float lightSpecIntensity = 1.0;
-
-// Material uniform values
-uniform vec3 matAmbientColor = vec3(1.0, 1.0, 1.0);
-uniform vec3 matSpecularColor = vec3(1.0, 1.0, 1.0);
-uniform float matGlossiness = 50.0;
-
-// World uniform values
-uniform vec3 lightPosition;
-uniform vec3 cameraPosition;
-
-// Fragment shader output data
-out vec4 fragColor;
-
-// Calculate ambient lighting component
-vec3 AmbientLighting()
-{
- return (matAmbientColor*lightAmbientColor);
-}
-
-// Calculate diffuse lighting component
-vec3 DiffuseLighting(in vec3 N, in vec3 L)
-{
- // Lambertian reflection calculation
- float diffuse = clamp(dot(N, L), 0, 1);
-
- return (colDiffuse.xyz*lightDiffuseColor*lightIntensity*diffuse);
-}
-
-// Calculate specular lighting component
-vec3 SpecularLighting(in vec3 N, in vec3 L, in vec3 V)
-{
- float specular = 0.0;
-
- // Calculate specular reflection only if the surface is oriented to the light source
- if (dot(N, L) > 0)
- {
- // Calculate half vector
- vec3 H = normalize(L + V);
-
- // Calculate specular intensity
- specular = pow(dot(N, H), 3 + matGlossiness);
- }
-
- return (matSpecularColor*lightSpecularColor*lightSpecIntensity*specular);
-}
-
-void main()
-{
- // Normalize input vectors
- vec3 L = normalize(lightPosition);
- vec3 V = normalize(cameraPosition);
- vec3 N = normalize(fragNormal);
-
- // Calculate lighting components
- vec3 ambient = AmbientLighting();
- vec3 diffuse = DiffuseLighting(N, L);
- vec3 specular = SpecularLighting(N, L, V);
-
- // Texel color fetching from texture sampler
- vec4 texelColor = texture(texture0, fragTexCoord);
-
- // Calculate final fragment color
- finalColor = vec4(texelColor.rgb*(ambient + diffuse + specular), texelColor.a);
-} \ No newline at end of file
diff --git a/shaders/glsl330/phong.vs b/shaders/glsl330/phong.vs
deleted file mode 100644
index d68d9b3f..00000000
--- a/shaders/glsl330/phong.vs
+++ /dev/null
@@ -1,29 +0,0 @@
-#version 330
-
-// Input vertex attributes
-in vec3 vertexPosition;
-in vec2 vertexTexCoord;
-in vec3 vertexNormal;
-
-// Input uniform values
-uniform mat4 mvpMatrix;
-
-// Output vertex attributes (to fragment shader)
-out vec2 fragTexCoord;
-out vec3 fragNormal;
-
-// NOTE: Add here your custom variables
-uniform mat4 modelMatrix;
-
-void main()
-{
- // Send vertex attributes to fragment shader
- fragTexCoord = vertexTexCoord;
-
- // Calculate view vector normal from model
- mat3 normalMatrix = transpose(inverse(mat3(modelMatrix)));
- fragNormal = normalize(normalMatrix*vertexNormal);
-
- // Calculate final vertex position
- gl_Position = mvpMatrix*vec4(vertexPosition, 1.0);
-} \ No newline at end of file
diff --git a/shaders/glsl330/pixel.fs b/shaders/glsl330/pixel.fs
index 9ed3ea7d..cf8aec44 100644
--- a/shaders/glsl330/pixel.fs
+++ b/shaders/glsl330/pixel.fs
@@ -6,15 +6,16 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
-const float renderWidth = 1280.0;
-const float renderHeight = 720.0;
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
uniform float pixelWidth = 5.0;
uniform float pixelHeight = 5.0;
diff --git a/shaders/glsl330/posterization.fs b/shaders/glsl330/posterization.fs
index f1d72a19..be2b5dd6 100644
--- a/shaders/glsl330/posterization.fs
+++ b/shaders/glsl330/posterization.fs
@@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
diff --git a/shaders/glsl330/predator.fs b/shaders/glsl330/predator.fs
index 9269dfd4..6a55c762 100644
--- a/shaders/glsl330/predator.fs
+++ b/shaders/glsl330/predator.fs
@@ -6,7 +6,7 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
diff --git a/shaders/glsl330/scanlines.fs b/shaders/glsl330/scanlines.fs
index 177f000d..22dc9cd5 100644
--- a/shaders/glsl330/scanlines.fs
+++ b/shaders/glsl330/scanlines.fs
@@ -6,20 +6,23 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
float offset = 0.0;
-float frequency = 720.0/3.0;
uniform float time;
void main()
{
+ float frequency = renderHeight/3.0;
/*
// Scanlines method 1
float tval = 0; //time
diff --git a/shaders/glsl330/standard.fs b/shaders/glsl330/standard.fs
index e5a6d1bc..f728be81 100644
--- a/shaders/glsl330/standard.fs
+++ b/shaders/glsl330/standard.fs
@@ -34,7 +34,6 @@ struct Light {
};
const int maxLights = 8;
-uniform int lightsCount;
uniform Light lights[maxLights];
vec3 CalcPointLight(Light l, vec3 n, vec3 v, float s)
@@ -134,19 +133,15 @@ void main()
float spec = 1.0;
if (useSpecular == 1) spec *= normalize(texture(texture2, fragTexCoord).r);
- for (int i = 0; i < lightsCount; i++)
+ for (int i = 0; i < maxLights; i++)
{
// Check if light is enabled
if (lights[i].enabled == 1)
{
// Calculate lighting based on light type
- switch (lights[i].type)
- {
- case 0: lighting += CalcPointLight(lights[i], n, v, spec); break;
- case 1: lighting += CalcDirectionalLight(lights[i], n, v, spec); break;
- case 2: lighting += CalcSpotLight(lights[i], n, v, spec); break;
- default: break;
- }
+ if(lights[i].type == 0) lighting += CalcPointLight(lights[i], n, v, spec);
+ else if(lights[i].type == 1) lighting += CalcDirectionalLight(lights[i], n, v, spec);
+ else if(lights[i].type == 2) lighting += CalcSpotLight(lights[i], n, v, spec);
}
}
diff --git a/shaders/glsl330/swirl.fs b/shaders/glsl330/swirl.fs
index 80c16cc9..c4b66768 100644
--- a/shaders/glsl330/swirl.fs
+++ b/shaders/glsl330/swirl.fs
@@ -6,15 +6,16 @@ in vec4 fragColor;
// Input uniform values
uniform sampler2D texture0;
-uniform vec4 fragTintColor;
+uniform vec4 colDiffuse;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
-const float renderWidth = 800.0; // HARDCODED for example!
-const float renderHeight = 480.0; // Use uniforms instead...
+// NOTE: Render size values must be passed from code
+const float renderWidth = 800;
+const float renderHeight = 450;
float radius = 250.0;
float angle = 0.8;
diff --git a/src/Makefile b/src/Makefile
index 3c66e4f4..ee3f0c12 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -35,7 +35,7 @@
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
PLATFORM ?= PLATFORM_DESKTOP
-# define if you want shared or static version of library.
+# define YES if you want shared/dynamic version of library instead of static (default)
SHARED ?= NO
# determine if the file has root access (only for installing raylib)
@@ -95,8 +95,13 @@ endif
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces
+# if shared library required, make sure code is compiled as position independent
ifeq ($(SHARED),YES)
CFLAGS += -fPIC
+ SHAREDFLAG = BUILDING_DLL
+ SHAREDLIBS = -Lexternal/glfw3/lib/win32 -Lexternal/openal_soft/lib/win32 -lglfw3 -lopenal32 -lgdi32
+else
+ SHAREDFLAG = BUILDING_STATIC
endif
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
@@ -152,12 +157,16 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
@echo "libraylib.bc generated (web version)!"
else
ifeq ($(SHARED),YES)
- ifeq ($(PLATFORM_OS),LINUX)
- # compile raylib to shared library version for GNU/Linux.
- # WARNING: you should type "make clean" before doing this target
- $(CC) -shared -o $(OUTPUT_PATH)/libraylib.so $(OBJS)
- @echo "libraylib.so generated (shared library)!"
- endif
+ ifeq ($(PLATFORM_OS),LINUX)
+ # compile raylib to shared library version for GNU/Linux.
+ # WARNING: you should type "make clean" before doing this target
+ $(CC) -shared -o $(OUTPUT_PATH)/libraylib.so $(OBJS)
+ @echo "raylib shared library (libraylib.so) generated!"
+ endif
+ ifeq ($(PLATFORM_OS),WINDOWS)
+ $(CC) -shared -o $(OUTPUT_PATH)/raylib.dll $(OBJS) $(SHAREDLIBS) -Wl,--out-implib,$(OUTPUT_PATH)/libraylibdll.a
+ @echo "raylib dynamic library (raylib.dll) and MSVC required import library (libraylibdll.a) generated!"
+ endif
else
# compile raylib static library for desktop platforms.
ar rcs $(OUTPUT_PATH)/libraylib.a $(OBJS)
@@ -168,32 +177,32 @@ endif
# compile all modules with their prerequisites
# compile core module
-core.o : core.c raylib.h rlgl.h utils.h raymath.h
- $(CC) -c $< $(CFLAGS) $(INCLUDE) -D$(PLATFORM)
+core.o : core.c raylib.h rlgl.h utils.h raymath.h gestures.h
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(SHAREDFLAG)
# compile rlgl module
rlgl.o : rlgl.c rlgl.h raymath.h
- $(CC) -c $< $(CFLAGS) $(INCLUDE) -D$(GRAPHICS)
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(GRAPHICS)
# compile shapes module
shapes.o : shapes.c raylib.h rlgl.h
- $(CC) -c $< $(CFLAGS) $(INCLUDE)
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(SHAREDFLAG)
# compile textures module
textures.o : textures.c rlgl.h utils.h
- $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS) -D$(SHAREDFLAG)
# compile text module
text.o : text.c raylib.h utils.h
- $(CC) -c $< $(CFLAGS) $(INCLUDE)
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(SHAREDFLAG)
# compile models module
models.o : models.c raylib.h rlgl.h raymath.h
- $(CC) -c $< $(CFLAGS) $(INCLUDE) -D$(PLATFORM)
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(SHAREDFLAG)
# compile audio module
audio.o : audio.c raylib.h
- $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(SHAREDFLAG)
# compile stb_vorbis library
external/stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h
@@ -201,15 +210,7 @@ external/stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h
# compile utils module
utils.o : utils.c utils.h
- $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
-
-# compile camera module
-camera.o : camera.c raylib.h
- $(CC) -c $< $(CFLAGS) $(INCLUDES)
-
-#compile gestures module
-gestures.o : gestures.c raylib.h
- $(CC) -c $< $(CFLAGS) $(INCLUDE)
+ $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(SHAREDFLAG)
# It installs generated and needed files to compile projects using raylib.
# The installation works manually.
@@ -222,10 +223,10 @@ ifeq ($(ROOT),root)
# /usr/local/include/) are for libraries that are installed
# manually (without a package manager).
ifeq ($(SHARED),YES)
- cp --update libraylib.so /usr/local/lib/libraylib.so
+ cp --update $(OUTPUT_PATH)/libraylib.so /usr/local/lib/libraylib.so
else
cp --update raylib.h /usr/local/include/raylib.h
- cp --update libraylib.a /usr/local/lib/libraylib.a
+ cp --update $(OUTPUT_PATH)/libraylib.a /usr/local/lib/libraylib.a
endif
@echo "raylib dev files installed/updated!"
else
diff --git a/src/android/jni/Android.mk b/src/android/jni/Android.mk
index 66851d08..687c6577 100644
--- a/src/android/jni/Android.mk
+++ b/src/android/jni/Android.mk
@@ -4,7 +4,7 @@
#
# Static library compilation
#
-# Copyright (c) 2014 Ramon Santamaria (Ray San - [email protected])
+# Copyright (c) 2014-2016 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.
@@ -42,7 +42,6 @@ LOCAL_SRC_FILES :=\
../../textures.c \
../../text.c \
../../shapes.c \
- ../../gestures.c \
../../models.c \
../../utils.c \
../../audio.c \
diff --git a/src/audio.c b/src/audio.c
index 38fefd12..90bf4968 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -2,7 +2,7 @@
*
* raylib.audio
*
-* Basic functions to manage Audio:
+* Basic functions to manage Audio:
* Manage audio device (init/close)
* Load and Unload audio files
* Play/Stop/Pause/Resume loaded audio
@@ -55,6 +55,7 @@
#include <string.h> // Required for: strcmp(), strncmp()
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
+// Tokens defined by OpenAL extension: AL_EXT_float32
#ifndef AL_FORMAT_MONO_FLOAT32
#define AL_FORMAT_MONO_FLOAT32 0x10010
#endif
@@ -78,75 +79,40 @@
#define JAR_MOD_IMPLEMENTATION
#include "external/jar_mod.h" // MOD loading functions
+#ifdef _MSC_VER
+ #undef bool
+#endif
+
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define MAX_STREAM_BUFFERS 2 // Number of buffers for each source
-#define MAX_MUSIC_STREAMS 2 // Number of simultanious music sources
-#define MAX_MIX_CHANNELS 4 // Number of mix channels (OpenAL sources)
-
-#if defined(PLATFORM_RPI) || defined(PLATFORM_ANDROID)
- // NOTE: On RPI and Android should be lower to avoid frame-stalls
- #define MUSIC_BUFFER_SIZE_SHORT 4096*2 // PCM data buffer (short) - 16Kb (RPI)
- #define MUSIC_BUFFER_SIZE_FLOAT 4096 // PCM data buffer (float) - 16Kb (RPI)
-#else
- // NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care...
- #define MUSIC_BUFFER_SIZE_SHORT 4096*8 // PCM data buffer (short) - 64Kb
- #define MUSIC_BUFFER_SIZE_FLOAT 4096*4 // PCM data buffer (float) - 64Kb
-#endif
+#define MAX_STREAM_BUFFERS 2 // Number of buffers for each audio stream
+
+// NOTE: Music buffer size is defined by number of samples, independent of sample size
+// After some math, considering a sampleRate of 48000, a buffer refill rate of 1/60 seconds
+// and double-buffering system, I concluded that a 4096 samples buffer should be enough
+// In case of music-stalls, just increase this number
+#define AUDIO_BUFFER_SIZE 4096 // PCM data samples (i.e. short: 32Kb)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
-// Used to create custom audio streams that are not bound to a specific file.
-// There can be no more than 4 concurrent mixchannels in use.
-// This is due to each active mixc being tied to a dedicated mix channel.
-typedef struct MixChannel {
- unsigned short sampleRate; // default is 48000
- unsigned char channels; // 1=mono,2=stereo
- unsigned char mixChannel; // 0-3 or mixA-mixD, each mix channel can receive up to one dedicated audio stream
- bool floatingPoint; // if false then the short datatype is used instead
- bool playing; // false if paused
-
- ALenum alFormat; // OpenAL format specifier
- ALuint alSource; // OpenAL source
- ALuint alBuffer[MAX_STREAM_BUFFERS]; // OpenAL sample buffer
-} MixChannel;
+typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_MODULE_XM, MUSIC_MODULE_MOD } MusicContextType;
// Music type (file streaming from memory)
-// NOTE: Anything longer than ~10 seconds should be streamed into a mix channel...
-typedef struct Music {
- stb_vorbis *stream;
- jar_xm_context_t *xmctx; // XM chiptune context
- jar_mod_context_t modctx; // MOD chiptune context
- MixChannel *mixc; // Mix channel
-
- unsigned int totalSamplesLeft;
- float totalLengthSeconds;
- bool loop;
- bool chipTune; // chiptune is loaded?
- bool enabled;
-} Music;
-
-// Audio errors registered
-typedef enum {
- ERROR_RAW_CONTEXT_CREATION = 1,
- ERROR_XM_CONTEXT_CREATION = 2,
- ERROR_MOD_CONTEXT_CREATION = 4,
- ERROR_MIX_CHANNEL_CREATION = 8,
- ERROR_MUSIC_CHANNEL_CREATION = 16,
- ERROR_LOADING_XM = 32,
- ERROR_LOADING_MOD = 64,
- ERROR_LOADING_WAV = 128,
- ERROR_LOADING_OGG = 256,
- ERROR_OUT_OF_MIX_CHANNELS = 512,
- ERROR_EXTENSION_NOT_RECOGNIZED = 1024,
- ERROR_UNABLE_TO_OPEN_RRES_FILE = 2048,
- ERROR_INVALID_RRES_FILE = 4096,
- ERROR_INVALID_RRES_RESOURCE = 8192,
- ERROR_UNINITIALIZED_CHANNELS = 16384
-} AudioError;
+typedef struct MusicData {
+ MusicContextType ctxType; // Type of music context (OGG, XM, MOD)
+ stb_vorbis *ctxOgg; // OGG audio context
+ jar_xm_context_t *ctxXm; // XM chiptune context
+ jar_mod_context_t ctxMod; // MOD chiptune context
+
+ AudioStream stream; // Audio stream (double buffering)
+
+ bool loop; // Repeat music after finish (loop)
+ unsigned int totalSamples; // Total number of samples
+ unsigned int samplesLeft; // Number of samples left to end
+} MusicData, *Music;
#if defined(AUDIO_STANDALONE)
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
@@ -155,26 +121,13 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
-static Music musicStreams[MAX_MUSIC_STREAMS]; // Current music loaded, up to two can play at the same time
-static MixChannel *mixChannels[MAX_MIX_CHANNELS]; // Mix channels currently active (from music streams)
-
-static int lastAudioError = 0; // Registers last audio error
+// ...
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-static Wave LoadWAV(const char *fileName); // Load WAV file
-static Wave LoadOGG(char *fileName); // Load OGG file
-static void UnloadWave(Wave wave); // Unload wave data
-
-static bool BufferMusicStream(int index, int numBuffers); // Fill music buffers with data
-static void EmptyMusicStream(int index); // Empty music buffers
-
-static MixChannel *InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint);
-static void CloseMixChannel(MixChannel *mixc); // Frees mix channel
-static int BufferMixChannel(MixChannel *mixc, void *data, int numberElements); // Pushes more audio data into mix channel
-//static void ResampleShortToFloat(short *shorts, float *floats, unsigned short len); // Pass two arrays of the same legnth in
-//static void ResampleByteToFloat(char *chars, float *floats, unsigned short len); // Pass two arrays of same length in
+static Wave LoadWAV(const char *fileName); // Load WAV file
+static Wave LoadOGG(const char *fileName); // Load OGG file
#if defined(AUDIO_STANDALONE)
const char *GetExtension(const char *fileName); // Get the extension for a filename
@@ -185,362 +138,120 @@ void TraceLog(int msgType, const char *text, ...); // Outputs a trace log messa
// Module Functions Definition - Audio Device initialization and Closing
//----------------------------------------------------------------------------------
-// Initialize audio device and mixc
+// Initialize audio device
void InitAudioDevice(void)
{
// Open and initialize a device with default settings
ALCdevice *device = alcOpenDevice(NULL);
if (!device) TraceLog(ERROR, "Audio device could not be opened");
-
- ALCcontext *context = alcCreateContext(device, NULL);
-
- if ((context == NULL) || (alcMakeContextCurrent(context) == ALC_FALSE))
+ else
{
- if (context != NULL) alcDestroyContext(context);
+ ALCcontext *context = alcCreateContext(device, NULL);
- alcCloseDevice(device);
+ if ((context == NULL) || (alcMakeContextCurrent(context) == ALC_FALSE))
+ {
+ if (context != NULL) alcDestroyContext(context);
- TraceLog(ERROR, "Could not setup mix channel");
- }
+ alcCloseDevice(device);
- TraceLog(INFO, "Audio device and context initialized successfully: %s", alcGetString(device, ALC_DEVICE_SPECIFIER));
+ TraceLog(ERROR, "Could not initialize audio context");
+ }
+ else
+ {
+ TraceLog(INFO, "Audio device and context initialized successfully: %s", alcGetString(device, ALC_DEVICE_SPECIFIER));
- // Listener definition (just for 2D)
- alListener3f(AL_POSITION, 0, 0, 0);
- alListener3f(AL_VELOCITY, 0, 0, 0);
- alListener3f(AL_ORIENTATION, 0, 0, -1);
+ // Listener definition (just for 2D)
+ alListener3f(AL_POSITION, 0, 0, 0);
+ alListener3f(AL_VELOCITY, 0, 0, 0);
+ alListener3f(AL_ORIENTATION, 0, 0, -1);
+ }
+ }
}
// Close the audio device for all contexts
void CloseAudioDevice(void)
{
- for (int index = 0; index < MAX_MUSIC_STREAMS; index++)
- {
- if (musicStreams[index].mixc) StopMusicStream(index); // Stop music streaming and close current stream
- }
-
ALCdevice *device;
ALCcontext *context = alcGetCurrentContext();
- if (context == NULL) TraceLog(WARNING, "Could not get current mix channel for closing");
+ if (context == NULL) TraceLog(WARNING, "Could not get current audio context for closing");
device = alcGetContextsDevice(context);
alcMakeContextCurrent(NULL);
alcDestroyContext(context);
alcCloseDevice(device);
+
+ TraceLog(INFO, "Audio device closed successfully");
}
// Check if device has been initialized successfully
bool IsAudioDeviceReady(void)
{
ALCcontext *context = alcGetCurrentContext();
-
+
if (context == NULL) return false;
else
{
ALCdevice *device = alcGetContextsDevice(context);
-
+
if (device == NULL) return false;
else return true;
}
}
//----------------------------------------------------------------------------------
-// Module Functions Definition - Custom audio output
+// Module Functions Definition - Sounds loading and playing (.WAV)
//----------------------------------------------------------------------------------
-// Init mix channel for streaming
-// The mixChannel is what audio muxing channel you want to operate on, 0-3 are the ones available.
-// Each mix channel can only be used one at a time.
-static MixChannel *InitMixChannel(unsigned short sampleRate, unsigned char mixChannel, unsigned char channels, bool floatingPoint)
+// Load wave data from file into RAM
+Wave LoadWave(const char *fileName)
{
- if (mixChannel >= MAX_MIX_CHANNELS) return NULL;
- if (!IsAudioDeviceReady()) InitAudioDevice();
-
- if (!mixChannels[mixChannel])
- {
- MixChannel *mixc = (MixChannel *)malloc(sizeof(MixChannel));
- mixc->sampleRate = sampleRate;
- mixc->channels = channels;
- mixc->mixChannel = mixChannel;
- mixc->floatingPoint = floatingPoint;
- mixChannels[mixChannel] = mixc;
-
- // Setup OpenAL format
- if (channels == 1)
- {
- if (floatingPoint) mixc->alFormat = AL_FORMAT_MONO_FLOAT32;
- else mixc->alFormat = AL_FORMAT_MONO16;
- }
- else if (channels == 2)
- {
- if (floatingPoint) mixc->alFormat = AL_FORMAT_STEREO_FLOAT32;
- else mixc->alFormat = AL_FORMAT_STEREO16;
- }
-
- // Create an audio source
- alGenSources(1, &mixc->alSource);
- alSourcef(mixc->alSource, AL_PITCH, 1);
- alSourcef(mixc->alSource, AL_GAIN, 1);
- alSource3f(mixc->alSource, AL_POSITION, 0, 0, 0);
- alSource3f(mixc->alSource, AL_VELOCITY, 0, 0, 0);
-
- // Create Buffer
- alGenBuffers(MAX_STREAM_BUFFERS, mixc->alBuffer);
-
- // Fill buffers
- for (int i = 0; i < MAX_STREAM_BUFFERS; i++)
- {
- // Initialize buffer with zeros by default
- if (mixc->floatingPoint)
- {
- float pcm[MUSIC_BUFFER_SIZE_FLOAT] = { 0.0f };
- alBufferData(mixc->alBuffer[i], mixc->alFormat, pcm, MUSIC_BUFFER_SIZE_FLOAT*sizeof(float), mixc->sampleRate);
- }
- else
- {
- short pcm[MUSIC_BUFFER_SIZE_SHORT] = { 0 };
- alBufferData(mixc->alBuffer[i], mixc->alFormat, pcm, MUSIC_BUFFER_SIZE_SHORT*sizeof(short), mixc->sampleRate);
- }
- }
-
- alSourceQueueBuffers(mixc->alSource, MAX_STREAM_BUFFERS, mixc->alBuffer);
- mixc->playing = true;
- alSourcePlay(mixc->alSource);
-
- return mixc;
- }
-
- return NULL;
-}
+ Wave wave = { 0 };
-// Frees buffer in mix channel
-static void CloseMixChannel(MixChannel *mixc)
-{
- if (mixc)
- {
- alSourceStop(mixc->alSource);
- mixc->playing = false;
-
- // Flush out all queued buffers
- ALuint buffer = 0;
- int queued = 0;
- alGetSourcei(mixc->alSource, AL_BUFFERS_QUEUED, &queued);
-
- while (queued > 0)
- {
- alSourceUnqueueBuffers(mixc->alSource, 1, &buffer);
- queued--;
- }
-
- // Delete source and buffers
- alDeleteSources(1, &mixc->alSource);
- alDeleteBuffers(MAX_STREAM_BUFFERS, mixc->alBuffer);
- mixChannels[mixc->mixChannel] = NULL;
- free(mixc);
- mixc = NULL;
- }
+ if (strcmp(GetExtension(fileName), "wav") == 0) wave = LoadWAV(fileName);
+ else if (strcmp(GetExtension(fileName), "ogg") == 0) wave = LoadOGG(fileName);
+ else TraceLog(WARNING, "[%s] File extension not recognized, it can't be loaded", fileName);
+
+ return wave;
}
-// Pushes more audio data into mix channel, only one buffer per call
-// Call "BufferMixChannel(mixc, NULL, 0)" if you want to pause the audio.
-// Returns number of samples that where processed.
-static int BufferMixChannel(MixChannel *mixc, void *data, int numberElements)
+// Load wave data from float array data (32bit)
+Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels)
{
- if (!mixc || (mixChannels[mixc->mixChannel] != mixc)) return 0; // When there is two channels there must be an even number of samples
-
- if (!data || !numberElements)
- {
- // Pauses audio until data is given
- if (mixc->playing)
- {
- alSourcePause(mixc->alSource);
- mixc->playing = false;
- }
-
- return 0;
- }
- else if (!mixc->playing)
- {
- // Restart audio otherwise
- alSourcePlay(mixc->alSource);
- mixc->playing = true;
- }
-
- ALuint buffer = 0;
+ Wave wave;
- alSourceUnqueueBuffers(mixc->alSource, 1, &buffer);
- if (!buffer) return 0;
+ wave.data = data;
+ wave.sampleCount = sampleCount;
+ wave.sampleRate = sampleRate;
+ wave.sampleSize = 32;
+ wave.channels = channels;
- if (mixc->floatingPoint)
- {
- // Process float buffers
- float *ptr = (float *)data;
- alBufferData(buffer, mixc->alFormat, ptr, numberElements*sizeof(float), mixc->sampleRate);
- }
- else
- {
- // Process short buffers
- short *ptr = (short *)data;
- alBufferData(buffer, mixc->alFormat, ptr, numberElements*sizeof(short), mixc->sampleRate);
- }
+ // NOTE: Copy wave data to work with,
+ // user is responsible of input data to free
+ Wave cwave = WaveCopy(wave);
- alSourceQueueBuffers(mixc->alSource, 1, &buffer);
+ WaveFormat(&cwave, sampleRate, sampleSize, channels);
- return numberElements;
-}
-
-/*
-// Convert data from short to float
-// example usage:
-// short sh[3] = {1,2,3};float fl[3];
-// ResampleShortToFloat(sh,fl,3);
-static void ResampleShortToFloat(short *shorts, float *floats, unsigned short len)
-{
- for (int i = 0; i < len; i++)
- {
- if (shorts[i] < 0) floats[i] = (float)shorts[i]/32766.0f;
- else floats[i] = (float)shorts[i]/32767.0f;
- }
+ return cwave;
}
-// Convert data from float to short
-// example usage:
-// char ch[3] = {1,2,3};float fl[3];
-// ResampleByteToFloat(ch,fl,3);
-static void ResampleByteToFloat(char *chars, float *floats, unsigned short len)
-{
- for (int i = 0; i < len; i++)
- {
- if (chars[i] < 0) floats[i] = (float)chars[i]/127.0f;
- else floats[i] = (float)chars[i]/128.0f;
- }
-}
-*/
-
-// Initialize raw audio mix channel for audio buffering
-// NOTE: Returns mix channel index or -1 if it fails (errors are registered on lastAudioError)
-int InitRawMixChannel(int sampleRate, int channels, bool floatingPoint)
-{
- int mixIndex;
-
- for (mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
- {
- if (mixChannels[mixIndex] == NULL) break;
- else if (mixIndex == (MAX_MIX_CHANNELS - 1))
- {
- lastAudioError = ERROR_OUT_OF_MIX_CHANNELS;
- return -1;
- }
- }
-
- if (InitMixChannel(sampleRate, mixIndex, channels, floatingPoint)) return mixIndex;
- else
- {
- lastAudioError = ERROR_RAW_CONTEXT_CREATION;
- return -1;
- }
-}
-
-// Buffers data directly to raw mix channel
-// if 0 is returned, buffers are still full and you need to keep trying with the same data
-// otherwise it will return number of samples buffered.
-// NOTE: Data could be either be an array of floats or shorts, depending on the created context
-int BufferRawAudioContext(int ctx, void *data, unsigned short numberElements)
+// Load sound to memory
+// NOTE: The entire file is loaded to memory to be played (no-streaming)
+Sound LoadSound(const char *fileName)
{
- int numBuffered = 0;
+ Wave wave = LoadWave(fileName);
- if (ctx >= 0)
- {
- MixChannel *mixc = mixChannels[ctx];
- numBuffered = BufferMixChannel(mixc, data, numberElements);
- }
+ Sound sound = LoadSoundFromWave(wave);
- return numBuffered;
-}
-
-// Closes and frees raw mix channel
-void CloseRawAudioContext(int ctx)
-{
- if (mixChannels[ctx]) CloseMixChannel(mixChannels[ctx]);
-}
-
-//----------------------------------------------------------------------------------
-// Module Functions Definition - Sounds loading and playing (.WAV)
-//----------------------------------------------------------------------------------
-
-// Load sound to memory
-Sound LoadSound(char *fileName)
-{
- Sound sound = { 0 };
- Wave wave = { 0 };
-
- // NOTE: The entire file is loaded to memory to play it all at once (no-streaming)
-
- // Audio file loading
- // NOTE: Buffer space is allocated inside function, Wave must be freed
-
- if (strcmp(GetExtension(fileName),"wav") == 0) wave = LoadWAV(fileName);
- else if (strcmp(GetExtension(fileName),"ogg") == 0) wave = LoadOGG(fileName);
- else
- {
- TraceLog(WARNING, "[%s] Sound extension not recognized, it can't be loaded", fileName);
-
- // TODO: Find a better way to register errors (similar to glGetError())
- lastAudioError = ERROR_EXTENSION_NOT_RECOGNIZED;
- }
-
- if (wave.data != NULL)
- {
- ALenum format = 0;
- // The OpenAL format is worked out by looking at the number of channels and the bits per sample
- if (wave.channels == 1)
- {
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
- }
- else if (wave.channels == 2)
- {
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
- }
-
- // Create an audio source
- ALuint source;
- alGenSources(1, &source); // Generate pointer to audio source
-
- alSourcef(source, AL_PITCH, 1);
- alSourcef(source, AL_GAIN, 1);
- alSource3f(source, AL_POSITION, 0, 0, 0);
- alSource3f(source, AL_VELOCITY, 0, 0, 0);
- alSourcei(source, AL_LOOPING, AL_FALSE);
-
- // Convert loaded data to OpenAL buffer
- //----------------------------------------
- ALuint buffer;
- alGenBuffers(1, &buffer); // Generate pointer to buffer
-
- // Upload sound data to buffer
- alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
-
- // Attach sound buffer to source
- alSourcei(source, AL_BUFFER, buffer);
-
- TraceLog(INFO, "[%s] Sound file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
-
- // Unallocate WAV data
- UnloadWave(wave);
-
- sound.source = source;
- sound.buffer = buffer;
- }
+ UnloadWave(wave); // Sound is loaded, we can unload wave
return sound;
}
// Load sound from wave data
+// NOTE: Wave data must be unallocated manually
Sound LoadSoundFromWave(Wave wave)
{
Sound sound = { 0 };
@@ -548,17 +259,29 @@ Sound LoadSoundFromWave(Wave wave)
if (wave.data != NULL)
{
ALenum format = 0;
- // The OpenAL format is worked out by looking at the number of channels and the bits per sample
+
+ // The OpenAL format is worked out by looking at the number of channels and the sample size (bits per sample)
if (wave.channels == 1)
{
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
+ switch (wave.sampleSize)
+ {
+ case 8: format = AL_FORMAT_MONO8; break;
+ case 16: format = AL_FORMAT_MONO16; break;
+ case 32: format = AL_FORMAT_MONO_FLOAT32; break;
+ default: TraceLog(WARNING, "Wave sample size not supported: %i", wave.sampleSize); break;
+ }
}
else if (wave.channels == 2)
{
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
+ switch (wave.sampleSize)
+ {
+ case 8: format = AL_FORMAT_STEREO8; break;
+ case 16: format = AL_FORMAT_STEREO16; break;
+ case 32: format = AL_FORMAT_STEREO_FLOAT32; break;
+ default: TraceLog(WARNING, "Wave sample size not supported: %i", wave.sampleSize); break;
+ }
}
+ else TraceLog(WARNING, "Wave number of channels not supported: %i", wave.channels);
// Create an audio source
ALuint source;
@@ -575,19 +298,19 @@ Sound LoadSoundFromWave(Wave wave)
ALuint buffer;
alGenBuffers(1, &buffer); // Generate pointer to buffer
+ unsigned int dataSize = wave.sampleCount*wave.sampleSize/8; // Size in bytes
+
// Upload sound data to buffer
- alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
+ alBufferData(buffer, format, wave.data, dataSize, wave.sampleRate);
// Attach sound buffer to source
alSourcei(source, AL_BUFFER, buffer);
- // Unallocate WAV data
- UnloadWave(wave);
-
- TraceLog(INFO, "[Wave] Sound file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", wave.sampleRate, wave.bitsPerSample, wave.channels);
+ TraceLog(INFO, "[SND ID %i][BUFR ID %i] Sound data loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", source, buffer, wave.sampleRate, wave.sampleSize, wave.channels);
sound.source = source;
sound.buffer = buffer;
+ sound.format = format;
}
return sound;
@@ -602,9 +325,9 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
#if defined(AUDIO_STANDALONE)
TraceLog(WARNING, "Sound loading from rRES resource file not supported on standalone mode");
#else
-
+
bool found = false;
-
+
char id[4]; // rRES file identifier
unsigned char version; // rRES file version and subversion
char useless; // rRES header reserved data
@@ -614,11 +337,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
FILE *rresFile = fopen(rresName, "rb");
- if (rresFile == NULL)
- {
- TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
- lastAudioError = ERROR_UNABLE_TO_OPEN_RRES_FILE;
- }
+ if (rresFile == NULL) TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
else
{
// Read rres file (basic file check - id)
@@ -632,7 +351,6 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
{
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
- lastAudioError = ERROR_INVALID_RRES_FILE;
}
else
{
@@ -664,8 +382,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
fread(&reserved, 1, 1, rresFile); // <reserved>
wave.sampleRate = sampleRate;
- wave.dataSize = infoHeader.srcSize;
- wave.bitsPerSample = bps;
+ wave.sampleSize = bps;
wave.channels = (short)channels;
unsigned char *data = malloc(infoHeader.size);
@@ -676,55 +393,12 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
free(data);
- // Convert wave to Sound (OpenAL)
- ALenum format = 0;
-
- // The OpenAL format is worked out by looking at the number of channels and the bits per sample
- if (wave.channels == 1)
- {
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
- }
- else if (wave.channels == 2)
- {
- if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
- else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
- }
-
- // Create an audio source
- ALuint source;
- alGenSources(1, &source); // Generate pointer to audio source
-
- alSourcef(source, AL_PITCH, 1);
- alSourcef(source, AL_GAIN, 1);
- alSource3f(source, AL_POSITION, 0, 0, 0);
- alSource3f(source, AL_VELOCITY, 0, 0, 0);
- alSourcei(source, AL_LOOPING, AL_FALSE);
-
- // Convert loaded data to OpenAL buffer
- //----------------------------------------
- ALuint buffer;
- alGenBuffers(1, &buffer); // Generate pointer to buffer
-
- // Upload sound data to buffer
- alBufferData(buffer, format, (void*)wave.data, wave.dataSize, wave.sampleRate);
-
- // Attach sound buffer to source
- alSourcei(source, AL_BUFFER, buffer);
-
- TraceLog(INFO, "[%s] Sound loaded successfully from resource (SampleRate: %i, BitRate: %i, Channels: %i)", rresName, wave.sampleRate, wave.bitsPerSample, wave.channels);
-
- // Unallocate WAV data
- UnloadWave(wave);
+ sound = LoadSoundFromWave(wave);
- sound.source = source;
- sound.buffer = buffer;
- }
- else
- {
- TraceLog(WARNING, "[%s] Required resource do not seem to be a valid SOUND resource", rresName);
- lastAudioError = ERROR_INVALID_RRES_RESOURCE;
+ // Sound is loaded, we can unload wave data
+ UnloadWave(wave);
}
+ else TraceLog(WARNING, "[%s] Required resource do not seem to be a valid SOUND resource", rresName);
}
else
{
@@ -753,13 +427,48 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
return sound;
}
+// Unload Wave data
+void UnloadWave(Wave wave)
+{
+ free(wave.data);
+
+ TraceLog(INFO, "Unloaded wave data from RAM");
+}
+
// Unload sound
void UnloadSound(Sound sound)
{
alDeleteSources(1, &sound.source);
alDeleteBuffers(1, &sound.buffer);
+
+ TraceLog(INFO, "[SND ID %i][BUFR ID %i] Unloaded sound data from RAM", sound.source, sound.buffer);
+}
+
+// Update sound buffer with new data
+// NOTE: data must match sound.format
+void UpdateSound(Sound sound, void *data, int numSamples)
+{
+ ALint sampleRate, sampleSize, channels;
+ alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate);
+ alGetBufferi(sound.buffer, AL_BITS, &sampleSize); // It could also be retrieved from sound.format
+ alGetBufferi(sound.buffer, AL_CHANNELS, &channels); // It could also be retrieved from sound.format
- TraceLog(INFO, "Unloaded sound data");
+ TraceLog(DEBUG, "UpdateSound() : AL_FREQUENCY: %i", sampleRate);
+ TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize);
+ TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels);
+
+ unsigned int dataSize = numSamples*sampleSize/8; // Size of data in bytes
+
+ alSourceStop(sound.source); // Stop sound
+ alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update
+ //alDeleteBuffers(1, &sound.buffer); // Delete current buffer data
+ //alGenBuffers(1, &sound.buffer); // Generate new buffer
+
+ // Upload new data to sound buffer
+ alBufferData(sound.buffer, sound.format, data, dataSize, sampleRate);
+
+ // Attach sound buffer to source again
+ alSourcei(sound.source, AL_BUFFER, sound.buffer);
}
// Play a sound
@@ -777,7 +486,7 @@ void PlaySound(Sound sound)
//int sampleRate;
//alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); // AL_CHANNELS, AL_BITS (bps)
- //float seconds = (float)byteOffset / sampleRate; // Number of seconds since the beginning of the sound
+ //float seconds = (float)byteOffset/sampleRate; // Number of seconds since the beginning of the sound
//or
//float result;
//alGetSourcef(sound.source, AL_SEC_OFFSET, &result); // AL_SAMPLE_OFFSET
@@ -789,6 +498,16 @@ void PauseSound(Sound sound)
alSourcePause(sound.source);
}
+// Resume a paused sound
+void ResumeSound(Sound sound)
+{
+ ALenum state;
+
+ alGetSourcei(sound.source, AL_SOURCE_STATE, &state);
+
+ if (state == AL_PAUSED) alSourcePlay(sound.source);
+}
+
// Stop reproducing a sound
void StopSound(Sound sound)
{
@@ -819,396 +538,538 @@ void SetSoundPitch(Sound sound, float pitch)
alSourcef(sound.source, AL_PITCH, pitch);
}
-//----------------------------------------------------------------------------------
-// Module Functions Definition - Music loading and stream playing (.OGG)
-//----------------------------------------------------------------------------------
-
-// Start music playing (open stream)
-// returns 0 on success or error code
-int PlayMusicStream(int index, char *fileName)
+// Convert wave data to desired format
+// TODO: Consider channels (mono - stereo)
+void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
{
- int mixIndex;
-
- if (musicStreams[index].stream || musicStreams[index].xmctx) return ERROR_UNINITIALIZED_CHANNELS; // error
-
- for (mixIndex = 0; mixIndex < MAX_MIX_CHANNELS; mixIndex++) // find empty mix channel slot
- {
- if (mixChannels[mixIndex] == NULL) break;
- else if (mixIndex == (MAX_MIX_CHANNELS - 1)) return ERROR_OUT_OF_MIX_CHANNELS; // error
- }
-
- if (strcmp(GetExtension(fileName),"ogg") == 0)
+ if (wave->sampleSize != sampleSize)
{
- // Open audio stream
- musicStreams[index].stream = stb_vorbis_open_filename(fileName, NULL, NULL);
+ float *samples = GetWaveData(*wave); //Color *pixels = GetImageData(*image);
- if (musicStreams[index].stream == NULL)
- {
- TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
- return ERROR_LOADING_OGG; // error
- }
- else
- {
- // Get file info
- stb_vorbis_info info = stb_vorbis_get_info(musicStreams[index].stream);
+ free(wave->data);
+
+ wave->sampleSize = sampleSize;
- TraceLog(INFO, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
- TraceLog(INFO, "[%s] Ogg channels: %i", fileName, info.channels);
- TraceLog(DEBUG, "[%s] Temp memory required: %i", fileName, info.temp_memory_required);
+ //sample *= 4.0f; // Arbitrary gain to get reasonable output volume...
+ //if (sample > 1.0f) sample = 1.0f;
+ //if (sample < -1.0f) sample = -1.0f;
- musicStreams[index].loop = true; // We loop by default
- musicStreams[index].enabled = true;
-
+ if (sampleSize == 8)
+ {
+ wave->data = (unsigned char *)malloc(wave->sampleCount*sizeof(unsigned char));
- musicStreams[index].totalSamplesLeft = (unsigned int)stb_vorbis_stream_length_in_samples(musicStreams[index].stream) * info.channels;
- musicStreams[index].totalLengthSeconds = stb_vorbis_stream_length_in_seconds(musicStreams[index].stream);
-
- if (info.channels == 2)
- {
- musicStreams[index].mixc = InitMixChannel(info.sample_rate, mixIndex, 2, false);
- musicStreams[index].mixc->playing = true;
- }
- else
+ for (int i = 0; i < wave->sampleCount; i++)
{
- musicStreams[index].mixc = InitMixChannel(info.sample_rate, mixIndex, 1, false);
- musicStreams[index].mixc->playing = true;
+ ((unsigned char *)wave->data)[i] = (unsigned char)((float)samples[i]*127 + 128);
}
-
- if (!musicStreams[index].mixc) return ERROR_LOADING_OGG; // error
}
- }
- else if (strcmp(GetExtension(fileName),"xm") == 0)
- {
- // only stereo is supported for xm
- if (!jar_xm_create_context_from_file(&musicStreams[index].xmctx, 48000, fileName))
+ else if (sampleSize == 16)
{
- musicStreams[index].chipTune = true;
- musicStreams[index].loop = true;
- jar_xm_set_max_loop_count(musicStreams[index].xmctx, 0); // infinite number of loops
- musicStreams[index].totalSamplesLeft = (unsigned int)jar_xm_get_remaining_samples(musicStreams[index].xmctx);
- musicStreams[index].totalLengthSeconds = ((float)musicStreams[index].totalSamplesLeft)/48000.0f;
- musicStreams[index].enabled = true;
+ wave->data = (short *)malloc(wave->sampleCount*sizeof(short));
- TraceLog(INFO, "[%s] XM number of samples: %i", fileName, musicStreams[index].totalSamplesLeft);
- TraceLog(INFO, "[%s] XM track length: %11.6f sec", fileName, musicStreams[index].totalLengthSeconds);
-
- musicStreams[index].mixc = InitMixChannel(48000, mixIndex, 2, true);
-
- if (!musicStreams[index].mixc) return ERROR_XM_CONTEXT_CREATION; // error
-
- musicStreams[index].mixc->playing = true;
+ for (int i = 0; i < wave->sampleCount; i++)
+ {
+ ((short *)wave->data)[i] = (short)((float)samples[i]*32000); // SHRT_MAX = 32767
+ }
}
- else
+ else if (sampleSize == 32)
{
- TraceLog(WARNING, "[%s] XM file could not be opened", fileName);
- return ERROR_LOADING_XM; // error
+ wave->data = (float *)malloc(wave->sampleCount*sizeof(float));
+
+ for (int i = 0; i < wave->sampleCount; i++)
+ {
+ ((float *)wave->data)[i] = (float)samples[i];
+ }
}
+ else TraceLog(WARNING, "Wave formatting: Sample size not supported");
+
+ free(samples);
}
- else if (strcmp(GetExtension(fileName),"mod") == 0)
+
+ // NOTE: Only supported 1 or 2 channels (mono or stereo)
+ if ((channels > 0) && (channels < 3) && (wave->channels != channels))
{
- jar_mod_init(&musicStreams[index].modctx);
-
- if (jar_mod_load_file(&musicStreams[index].modctx, fileName))
- {
- musicStreams[index].chipTune = true;
- musicStreams[index].loop = true;
- musicStreams[index].totalSamplesLeft = (unsigned int)jar_mod_max_samples(&musicStreams[index].modctx);
- musicStreams[index].totalLengthSeconds = ((float)musicStreams[index].totalSamplesLeft)/48000.0f;
- musicStreams[index].enabled = true;
-
- TraceLog(INFO, "[%s] MOD number of samples: %i", fileName, musicStreams[index].totalSamplesLeft);
- TraceLog(INFO, "[%s] MOD track length: %11.6f sec", fileName, musicStreams[index].totalLengthSeconds);
-
- musicStreams[index].mixc = InitMixChannel(48000, mixIndex, 2, false);
-
- if (!musicStreams[index].mixc) return ERROR_MOD_CONTEXT_CREATION; // error
-
- musicStreams[index].mixc->playing = true;
- }
- else
- {
- TraceLog(WARNING, "[%s] MOD file could not be opened", fileName);
- return ERROR_LOADING_MOD; // error
- }
+ // TODO: Add/remove channels interlaced data if required...
}
- else
+}
+
+// Copy a wave to a new wave
+Wave WaveCopy(Wave wave)
+{
+ Wave newWave;
+
+ if (wave.sampleSize == 8) newWave.data = (unsigned char *)malloc(wave.sampleCount*wave.channels*sizeof(unsigned char));
+ else if (wave.sampleSize == 16) newWave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short));
+ else if (wave.sampleSize == 32) newWave.data = (float *)malloc(wave.sampleCount*wave.channels*sizeof(float));
+ else TraceLog(WARNING, "Wave sample size not supported for copy");
+
+ if (newWave.data != NULL)
{
- TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
- return ERROR_EXTENSION_NOT_RECOGNIZED; // error
+ // NOTE: Size must be provided in bytes
+ memcpy(newWave.data, wave.data, wave.sampleCount*wave.channels*wave.sampleSize/8);
+
+ newWave.sampleCount = wave.sampleCount;
+ newWave.sampleRate = wave.sampleRate;
+ newWave.sampleSize = wave.sampleSize;
+ newWave.channels = wave.channels;
}
-
- return 0; // normal return
+
+ return newWave;
}
-// Stop music playing for individual music index of musicStreams array (close stream)
-void StopMusicStream(int index)
+// Crop a wave to defined samples range
+// NOTE: Security check in case of out-of-range
+void WaveCrop(Wave *wave, int initSample, int finalSample)
{
- if (index < MAX_MUSIC_STREAMS && musicStreams[index].mixc)
+ if ((initSample >= 0) && (initSample < finalSample) &&
+ (finalSample > 0) && (finalSample < wave->sampleCount))
{
- CloseMixChannel(musicStreams[index].mixc);
-
- if (musicStreams[index].xmctx)
- jar_xm_free_context(musicStreams[index].xmctx);
- else if (musicStreams[index].modctx.mod_loaded)
- jar_mod_unload(&musicStreams[index].modctx);
- else
- stb_vorbis_close(musicStreams[index].stream);
+ // TODO: Review cropping (it could be simplified...)
- musicStreams[index].enabled = false;
+ float *samples = GetWaveData(*wave);
+ float *cropSamples = (float *)malloc((finalSample - initSample)*sizeof(float));
- if (musicStreams[index].stream || musicStreams[index].xmctx)
- {
- musicStreams[index].stream = NULL;
- musicStreams[index].xmctx = NULL;
- }
+ for (int i = initSample; i < finalSample; i++) cropSamples[i] = samples[i];
+
+ free(wave->data);
+ wave->data = cropSamples;
+ int sampleSize = wave->sampleSize;
+ wave->sampleSize = 32;
+
+ WaveFormat(wave, wave->sampleRate, sampleSize, wave->channels);
}
+ else TraceLog(WARNING, "Wave crop range out of bounds");
}
-// Update (re-fill) music buffers if data already processed
-void UpdateMusicStream(int index)
+// Get samples data from wave as a floats array
+// NOTE: Returned sample values are normalized to range [-1..1]
+// TODO: Consider multiple channels (mono - stereo)
+float *GetWaveData(Wave wave)
{
- ALenum state;
- bool active = true;
- ALint processed = 0;
+ float *samples = (float *)malloc(wave.sampleCount*sizeof(float));
- // Determine if music stream is ready to be written
- alGetSourcei(musicStreams[index].mixc->alSource, AL_BUFFERS_PROCESSED, &processed);
+ for (int i = 0; i < wave.sampleCount; i++)
+ {
+ if (wave.sampleSize == 8) samples[i] = (float)(((unsigned char *)wave.data)[i] - 127)/256.0f;
+ else if (wave.sampleSize == 16) samples[i] = (float)((short *)wave.data)[i]/32767.0f;
+ else if (wave.sampleSize == 32) samples[i] = ((float *)wave.data)[i];
+ }
- if (musicStreams[index].mixc->playing && (index < MAX_MUSIC_STREAMS) && musicStreams[index].enabled && musicStreams[index].mixc && (processed > 0))
+ return samples;
+}
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition - Music loading and stream playing (.OGG)
+//----------------------------------------------------------------------------------
+
+// Load music stream from file
+Music LoadMusicStream(const char *fileName)
+{
+ Music music = (MusicData *)malloc(sizeof(MusicData));
+
+ if (strcmp(GetExtension(fileName), "ogg") == 0)
{
- active = BufferMusicStream(index, processed);
-
- if (!active && musicStreams[index].loop)
+ // Open ogg audio stream
+ music->ctxOgg = stb_vorbis_open_filename(fileName, NULL, NULL);
+
+ if (music->ctxOgg == NULL) TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
+ else
{
- if (musicStreams[index].chipTune)
- {
- if(musicStreams[index].modctx.mod_loaded) jar_mod_seek_start(&musicStreams[index].modctx);
-
- musicStreams[index].totalSamplesLeft = musicStreams[index].totalLengthSeconds*48000.0f;
- }
- else
- {
- stb_vorbis_seek_start(musicStreams[index].stream);
- musicStreams[index].totalSamplesLeft = stb_vorbis_stream_length_in_samples(musicStreams[index].stream)*musicStreams[index].mixc->channels;
- }
-
- // Determine if music stream is ready to be written
- alGetSourcei(musicStreams[index].mixc->alSource, AL_BUFFERS_PROCESSED, &processed);
-
- active = BufferMusicStream(index, processed);
+ stb_vorbis_info info = stb_vorbis_get_info(music->ctxOgg); // Get Ogg file info
+ //float totalLengthSeconds = stb_vorbis_stream_length_in_seconds(music->ctxOgg);
+
+ // TODO: Support 32-bit sampleSize OGGs
+ music->stream = InitAudioStream(info.sample_rate, 16, info.channels);
+ music->totalSamples = (unsigned int)stb_vorbis_stream_length_in_samples(music->ctxOgg)*info.channels;
+ music->samplesLeft = music->totalSamples;
+ music->ctxType = MUSIC_AUDIO_OGG;
+ music->loop = true; // We loop by default
+
+ TraceLog(DEBUG, "[%s] OGG sample rate: %i", fileName, info.sample_rate);
+ TraceLog(DEBUG, "[%s] OGG channels: %i", fileName, info.channels);
+ TraceLog(DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required);
+
}
+ }
+ else if (strcmp(GetExtension(fileName), "xm") == 0)
+ {
+ int result = jar_xm_create_context_from_file(&music->ctxXm, 48000, fileName);
- if (alGetError() != AL_NO_ERROR) TraceLog(WARNING, "Error buffering data...");
-
- alGetSourcei(musicStreams[index].mixc->alSource, AL_SOURCE_STATE, &state);
+ if (!result) // XM context created successfully
+ {
+ jar_xm_set_max_loop_count(music->ctxXm, 0); // Set infinite number of loops
- if (state != AL_PLAYING && active) alSourcePlay(musicStreams[index].mixc->alSource);
+ // NOTE: Only stereo is supported for XM
+ music->stream = InitAudioStream(48000, 32, 2);
+ music->totalSamples = (unsigned int)jar_xm_get_remaining_samples(music->ctxXm);
+ music->samplesLeft = music->totalSamples;
+ music->ctxType = MUSIC_MODULE_XM;
+ music->loop = true;
- if (!active) StopMusicStream(index);
-
+ TraceLog(DEBUG, "[%s] XM number of samples: %i", fileName, music->totalSamples);
+ TraceLog(DEBUG, "[%s] XM track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f);
+ }
+ else TraceLog(WARNING, "[%s] XM file could not be opened", fileName);
}
+ else if (strcmp(GetExtension(fileName), "mod") == 0)
+ {
+ jar_mod_init(&music->ctxMod);
+
+ if (jar_mod_load_file(&music->ctxMod, fileName))
+ {
+ music->stream = InitAudioStream(48000, 16, 2);
+ music->totalSamples = (unsigned int)jar_mod_max_samples(&music->ctxMod);
+ music->samplesLeft = music->totalSamples;
+ music->ctxType = MUSIC_MODULE_MOD;
+ music->loop = true;
+
+ TraceLog(INFO, "[%s] MOD number of samples: %i", fileName, music->samplesLeft);
+ TraceLog(INFO, "[%s] MOD track length: %11.6f sec", fileName, (float)music->totalSamples/48000.0f);
+ }
+ else TraceLog(WARNING, "[%s] MOD file could not be opened", fileName);
+ }
+ else TraceLog(WARNING, "[%s] Music extension not recognized, it can't be loaded", fileName);
+
+ return music;
}
-//get number of music channels active at this time, this does not mean they are playing
-int GetMusicStreamCount(void)
+// Unload music stream
+void UnloadMusicStream(Music music)
{
- int musicCount = 0;
-
- // Find empty music slot
- for (int musicIndex = 0; musicIndex < MAX_MUSIC_STREAMS; musicIndex++)
- {
- if(musicStreams[musicIndex].stream != NULL || musicStreams[musicIndex].chipTune) musicCount++;
- }
-
- return musicCount;
+ CloseAudioStream(music->stream);
+
+ if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close(music->ctxOgg);
+ else if (music->ctxType == MUSIC_MODULE_XM) jar_xm_free_context(music->ctxXm);
+ else if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_unload(&music->ctxMod);
+
+ free(music);
+}
+
+// Start music playing (open stream)
+void PlayMusicStream(Music music)
+{
+ alSourcePlay(music->stream.source);
}
// Pause music playing
-void PauseMusicStream(int index)
+void PauseMusicStream(Music music)
+{
+ alSourcePause(music->stream.source);
+}
+
+// Resume music playing
+void ResumeMusicStream(Music music)
+{
+ ALenum state;
+ alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state);
+
+ if (state == AL_PAUSED) alSourcePlay(music->stream.source);
+}
+
+// Stop music playing (close stream)
+// TODO: Restart XM context
+void StopMusicStream(Music music)
{
- // Pause music stream if music available!
- if (index < MAX_MUSIC_STREAMS && musicStreams[index].mixc && musicStreams[index].enabled)
+ alSourceStop(music->stream.source);
+
+ switch (music->ctxType)
{
- TraceLog(INFO, "Pausing music stream");
- alSourcePause(musicStreams[index].mixc->alSource);
- musicStreams[index].mixc->playing = false;
+ case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break;
+ case MUSIC_MODULE_XM: break;
+ case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break;
+ default: break;
}
+
+ music->samplesLeft = music->totalSamples;
}
-// Resume music playing
-void ResumeMusicStream(int index)
+// Update (re-fill) music buffers if data already processed
+void UpdateMusicStream(Music music)
{
- // Resume music playing... if music available!
ALenum state;
+ ALint processed = 0;
- if (index < MAX_MUSIC_STREAMS && musicStreams[index].mixc)
+ alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state); // Get music stream state
+ alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); // Get processed buffers
+
+ if (processed > 0)
{
- alGetSourcei(musicStreams[index].mixc->alSource, AL_SOURCE_STATE, &state);
+ bool active = true;
+ short pcm[AUDIO_BUFFER_SIZE];
+ float pcmf[AUDIO_BUFFER_SIZE];
+ int numBuffersToProcess = processed;
+
+ int numSamples = 0; // Total size of data steamed in L+R samples for xm floats,
+ // individual L or R for ogg shorts
+
+ for (int i = 0; i < numBuffersToProcess; i++)
+ {
+ switch (music->ctxType)
+ {
+ case MUSIC_AUDIO_OGG:
+ {
+ if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE;
+ else numSamples = music->samplesLeft;
+
+ // NOTE: Returns the number of samples to process (should be the same as numSamples -> it is)
+ int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, pcm, numSamples);
+
+ // TODO: Review stereo channels Ogg, not enough samples served!
+ UpdateAudioStream(music->stream, pcm, numSamplesOgg*music->stream.channels);
+ music->samplesLeft -= (numSamplesOgg*music->stream.channels);
+
+ } break;
+ case MUSIC_MODULE_XM:
+ {
+ if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2;
+ else numSamples = music->samplesLeft;
+
+ // NOTE: Output buffer is 2*numsamples elements (left and right value for each sample)
+ jar_xm_generate_samples(music->ctxXm, pcmf, numSamples);
+ UpdateAudioStream(music->stream, pcmf, numSamples*2); // Using 32bit PCM data
+ music->samplesLeft -= numSamples;
+
+ //TraceLog(INFO, "Samples left: %i", music->samplesLeft);
+
+ } break;
+ case MUSIC_MODULE_MOD:
+ {
+ if (music->samplesLeft >= AUDIO_BUFFER_SIZE/2) numSamples = AUDIO_BUFFER_SIZE/2;
+ else numSamples = music->samplesLeft;
+
+ // NOTE: Output buffer size is nbsample*channels (default: 48000Hz, 16bit, Stereo)
+ jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0);
+ UpdateAudioStream(music->stream, pcm, numSamples*2);
+ music->samplesLeft -= numSamples;
+
+ } break;
+ default: break;
+ }
+
+ if (music->samplesLeft <= 0)
+ {
+ active = false;
+ break;
+ }
+ }
- if (state == AL_PAUSED)
+ // This error is registered when UpdateAudioStream() fails
+ if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data...");
+
+ // Reset audio stream for looping
+ if (!active)
+ {
+ StopMusicStream(music); // Stop music (and reset)
+
+ if (music->loop) PlayMusicStream(music); // Play again
+ }
+ else
{
- TraceLog(INFO, "Resuming music stream");
- alSourcePlay(musicStreams[index].mixc->alSource);
- musicStreams[index].mixc->playing = true;
+ // NOTE: In case window is minimized, music stream is stopped,
+ // just make sure to play again on window restore
+ if (state != AL_PLAYING) PlayMusicStream(music);
}
}
}
// Check if any music is playing
-bool IsMusicPlaying(int index)
+bool IsMusicPlaying(Music music)
{
bool playing = false;
ALint state;
-
- if (index < MAX_MUSIC_STREAMS && musicStreams[index].mixc)
- {
- alGetSourcei(musicStreams[index].mixc->alSource, AL_SOURCE_STATE, &state);
-
- if (state == AL_PLAYING) playing = true;
- }
+
+ alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state);
+
+ if (state == AL_PLAYING) playing = true;
return playing;
}
// Set volume for music
-void SetMusicVolume(int index, float volume)
+void SetMusicVolume(Music music, float volume)
{
- if (index < MAX_MUSIC_STREAMS && musicStreams[index].mixc)
- {
- alSourcef(musicStreams[index].mixc->alSource, AL_GAIN, volume);
- }
+ alSourcef(music->stream.source, AL_GAIN, volume);
}
// Set pitch for music
-void SetMusicPitch(int index, float pitch)
+void SetMusicPitch(Music music, float pitch)
{
- if (index < MAX_MUSIC_STREAMS && musicStreams[index].mixc)
- {
- alSourcef(musicStreams[index].mixc->alSource, AL_PITCH, pitch);
- }
+ alSourcef(music->stream.source, AL_PITCH, pitch);
}
// Get music time length (in seconds)
-float GetMusicTimeLength(int index)
+float GetMusicTimeLength(Music music)
{
- float totalSeconds;
-
- if (musicStreams[index].chipTune) totalSeconds = (float)musicStreams[index].totalLengthSeconds;
- else totalSeconds = stb_vorbis_stream_length_in_seconds(musicStreams[index].stream);
+ float totalSeconds = (float)music->totalSamples/music->stream.sampleRate;
return totalSeconds;
}
// Get current music time played (in seconds)
-float GetMusicTimePlayed(int index)
+float GetMusicTimePlayed(Music music)
{
float secondsPlayed = 0.0f;
-
- if (index < MAX_MUSIC_STREAMS && musicStreams[index].mixc)
+
+ unsigned int samplesPlayed = music->totalSamples - music->samplesLeft;
+ secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels);
+
+ return secondsPlayed;
+}
+
+// Init audio stream (to stream audio pcm data)
+AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, unsigned int channels)
+{
+ AudioStream stream = { 0 };
+
+ stream.sampleRate = sampleRate;
+ stream.sampleSize = sampleSize;
+ stream.channels = channels;
+
+ // Setup OpenAL format
+ if (channels == 1)
{
- if (musicStreams[index].chipTune && musicStreams[index].xmctx)
- {
- uint64_t samples;
- jar_xm_get_position(musicStreams[index].xmctx, NULL, NULL, NULL, &samples);
- secondsPlayed = (float)samples/(48000.0f*musicStreams[index].mixc->channels); // Not sure if this is the correct value
- }
- else if(musicStreams[index].chipTune && musicStreams[index].modctx.mod_loaded)
+ switch (sampleSize)
{
- long numsamp = jar_mod_current_samples(&musicStreams[index].modctx);
- secondsPlayed = (float)numsamp/(48000.0f);
+ case 8: stream.format = AL_FORMAT_MONO8; break;
+ case 16: stream.format = AL_FORMAT_MONO16; break;
+ case 32: stream.format = AL_FORMAT_MONO_FLOAT32; break;
+ default: TraceLog(WARNING, "Init audio stream: Sample size not supported: %i", sampleSize); break;
}
- else
+ }
+ else if (channels == 2)
+ {
+ switch (sampleSize)
{
- int totalSamples = stb_vorbis_stream_length_in_samples(musicStreams[index].stream)*musicStreams[index].mixc->channels;
- int samplesPlayed = totalSamples - musicStreams[index].totalSamplesLeft;
- secondsPlayed = (float)samplesPlayed/(musicStreams[index].mixc->sampleRate*musicStreams[index].mixc->channels);
+ case 8: stream.format = AL_FORMAT_STEREO8; break;
+ case 16: stream.format = AL_FORMAT_STEREO16; break;
+ case 32: stream.format = AL_FORMAT_STEREO_FLOAT32; break;
+ default: TraceLog(WARNING, "Init audio stream: Sample size not supported: %i", sampleSize); break;
}
}
+ else TraceLog(WARNING, "Init audio stream: Number of channels not supported: %i", channels);
- return secondsPlayed;
-}
+ // Create an audio source
+ alGenSources(1, &stream.source);
+ alSourcef(stream.source, AL_PITCH, 1);
+ alSourcef(stream.source, AL_GAIN, 1);
+ alSource3f(stream.source, AL_POSITION, 0, 0, 0);
+ alSource3f(stream.source, AL_VELOCITY, 0, 0, 0);
-//----------------------------------------------------------------------------------
-// Module specific Functions Definition
-//----------------------------------------------------------------------------------
+ // Create Buffers (double buffering)
+ alGenBuffers(MAX_STREAM_BUFFERS, stream.buffers);
-// Fill music buffers with new data from music stream
-static bool BufferMusicStream(int index, int numBuffers)
-{
- short pcm[MUSIC_BUFFER_SIZE_SHORT];
- float pcmf[MUSIC_BUFFER_SIZE_FLOAT];
-
- int size = 0; // Total size of data steamed in L+R samples for xm floats, individual L or R for ogg shorts
- bool active = true; // We can get more data from stream (not finished)
-
- if (musicStreams[index].chipTune) // There is no end of stream for xmfiles, once the end is reached zeros are generated for non looped chiptunes.
+ // Initialize buffer with zeros by default
+ for (int i = 0; i < MAX_STREAM_BUFFERS; i++)
{
- for (int i = 0; i < numBuffers; i++)
+ if (stream.sampleSize == 8)
{
- if (musicStreams[index].modctx.mod_loaded)
- {
- if (musicStreams[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT) size = MUSIC_BUFFER_SIZE_SHORT/2;
- else size = musicStreams[index].totalSamplesLeft/2;
-
- jar_mod_fillbuffer(&musicStreams[index].modctx, pcm, size, 0 );
- BufferMixChannel(musicStreams[index].mixc, pcm, size*2);
- }
- else if (musicStreams[index].xmctx)
- {
- if (musicStreams[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_FLOAT) size = MUSIC_BUFFER_SIZE_FLOAT/2;
- else size = musicStreams[index].totalSamplesLeft/2;
-
- jar_xm_generate_samples(musicStreams[index].xmctx, pcmf, size); // reads 2*readlen shorts and moves them to buffer+size memory location
- BufferMixChannel(musicStreams[index].mixc, pcmf, size*2);
- }
-
- musicStreams[index].totalSamplesLeft -= size;
-
- if (musicStreams[index].totalSamplesLeft <= 0)
- {
- active = false;
- break;
- }
+ unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 };
+ alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(unsigned char), stream.sampleRate);
}
- }
- else
- {
- if (musicStreams[index].totalSamplesLeft >= MUSIC_BUFFER_SIZE_SHORT) size = MUSIC_BUFFER_SIZE_SHORT;
- else size = musicStreams[index].totalSamplesLeft;
-
- for (int i = 0; i < numBuffers; i++)
+ else if (stream.sampleSize == 16)
{
- int streamedBytes = stb_vorbis_get_samples_short_interleaved(musicStreams[index].stream, musicStreams[index].mixc->channels, pcm, size);
- BufferMixChannel(musicStreams[index].mixc, pcm, streamedBytes * musicStreams[index].mixc->channels);
- musicStreams[index].totalSamplesLeft -= streamedBytes * musicStreams[index].mixc->channels;
-
- if (musicStreams[index].totalSamplesLeft <= 0)
- {
- active = false;
- break;
- }
+ short pcm[AUDIO_BUFFER_SIZE] = { 0 };
+ alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(short), stream.sampleRate);
+ }
+ else if (stream.sampleSize == 32)
+ {
+ float pcm[AUDIO_BUFFER_SIZE] = { 0.0f };
+ alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(float), stream.sampleRate);
}
}
- return active;
+ alSourceQueueBuffers(stream.source, MAX_STREAM_BUFFERS, stream.buffers);
+
+ TraceLog(INFO, "[AUD ID %i] Audio stream loaded successfully", stream.source);
+
+ return stream;
}
-// Empty music buffers
-static void EmptyMusicStream(int index)
+// Close audio stream and free memory
+void CloseAudioStream(AudioStream stream)
{
- ALuint buffer = 0;
+ // Stop playing channel
+ alSourceStop(stream.source);
+
+ // Flush out all queued buffers
int queued = 0;
+ alGetSourcei(stream.source, AL_BUFFERS_QUEUED, &queued);
- alGetSourcei(musicStreams[index].mixc->alSource, AL_BUFFERS_QUEUED, &queued);
+ ALuint buffer = 0;
while (queued > 0)
{
- alSourceUnqueueBuffers(musicStreams[index].mixc->alSource, 1, &buffer);
-
+ alSourceUnqueueBuffers(stream.source, 1, &buffer);
queued--;
}
+
+ // Delete source and buffers
+ alDeleteSources(1, &stream.source);
+ alDeleteBuffers(MAX_STREAM_BUFFERS, stream.buffers);
+
+ TraceLog(INFO, "[AUD ID %i] Unloaded audio stream data", stream.source);
}
+// Update audio stream buffers with data
+// NOTE: Only one buffer per call
+void UpdateAudioStream(AudioStream stream, void *data, int numSamples)
+{
+ ALuint buffer = 0;
+ alSourceUnqueueBuffers(stream.source, 1, &buffer);
+
+ // Check if any buffer was available for unqueue
+ if (alGetError() != AL_INVALID_VALUE)
+ {
+ if (stream.sampleSize == 8) alBufferData(buffer, stream.format, (unsigned char *)data, numSamples*sizeof(unsigned char), stream.sampleRate);
+ else if (stream.sampleSize == 16) alBufferData(buffer, stream.format, (short *)data, numSamples*sizeof(short), stream.sampleRate);
+ else if (stream.sampleSize == 32) alBufferData(buffer, stream.format, (float *)data, numSamples*sizeof(float), stream.sampleRate);
+
+ alSourceQueueBuffers(stream.source, 1, &buffer);
+ }
+}
+
+// Check if any audio stream buffers requires refill
+bool IsAudioBufferProcessed(AudioStream stream)
+{
+ ALint processed = 0;
+
+ // Determine if music stream is ready to be written
+ alGetSourcei(stream.source, AL_BUFFERS_PROCESSED, &processed);
+
+ return (processed > 0);
+}
+
+// Play audio stream
+void PlayAudioStream(AudioStream stream)
+{
+ alSourcePlay(stream.source);
+}
+
+// Play audio stream
+void PauseAudioStream(AudioStream stream)
+{
+ alSourcePause(stream.source);
+}
+
+// Resume audio stream playing
+void ResumeAudioStream(AudioStream stream)
+{
+ ALenum state;
+ alGetSourcei(stream.source, AL_SOURCE_STATE, &state);
+
+ if (state == AL_PAUSED) alSourcePlay(stream.source);
+}
+
+// Stop audio stream
+void StopAudioStream(AudioStream stream)
+{
+ alSourceStop(stream.source);
+}
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
+
// Load WAV file into Wave structure
static Wave LoadWAV(const char *fileName)
{
@@ -1288,18 +1149,18 @@ static Wave LoadWAV(const char *fileName)
else
{
// Allocate memory for data
- wave.data = (unsigned char *)malloc(sizeof(unsigned char) * waveData.subChunkSize);
+ wave.data = (unsigned char *)malloc(sizeof(unsigned char)*waveData.subChunkSize);
// Read in the sound data into the soundData variable
fread(wave.data, waveData.subChunkSize, 1, wavFile);
// Now we set the variables that we need later
- wave.dataSize = waveData.subChunkSize;
+ wave.sampleCount = waveData.subChunkSize;
wave.sampleRate = waveFormat.sampleRate;
+ wave.sampleSize = waveFormat.bitsPerSample;
wave.channels = waveFormat.numChannels;
- wave.bitsPerSample = waveFormat.bitsPerSample;
- TraceLog(INFO, "[%s] WAV file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
+ TraceLog(INFO, "[%s] WAV file loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", fileName, wave.sampleRate, wave.sampleSize, wave.channels);
}
}
}
@@ -1312,7 +1173,7 @@ static Wave LoadWAV(const char *fileName)
// Load OGG file into Wave structure
// NOTE: Using stb_vorbis library
-static Wave LoadOGG(char *fileName)
+static Wave LoadOGG(const char *fileName)
{
Wave wave;
@@ -1328,35 +1189,24 @@ static Wave LoadOGG(char *fileName)
stb_vorbis_info info = stb_vorbis_get_info(oggFile);
wave.sampleRate = info.sample_rate;
- wave.bitsPerSample = 16;
+ wave.sampleSize = 16; // 16 bit per sample (short)
wave.channels = info.channels;
- TraceLog(DEBUG, "[%s] Ogg sample rate: %i", fileName, info.sample_rate);
- TraceLog(DEBUG, "[%s] Ogg channels: %i", fileName, info.channels);
-
- int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile) * info.channels);
-
- wave.dataSize = totalSamplesLength*sizeof(short); // Size must be in bytes
-
- TraceLog(DEBUG, "[%s] Samples length: %i", fileName, totalSamplesLength);
-
+ int totalSamplesLength = (stb_vorbis_stream_length_in_samples(oggFile)*info.channels);
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
- TraceLog(DEBUG, "[%s] Total seconds: %f", fileName, totalSeconds);
-
if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
int totalSamples = totalSeconds*info.sample_rate*info.channels;
+ wave.sampleCount = totalSamples;
- TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
+ wave.data = (short *)malloc(totalSamplesLength*sizeof(short));
- wave.data = malloc(sizeof(short)*totalSamplesLength);
-
- int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
+ int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, (short *)wave.data, totalSamplesLength);
TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
- TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
+ TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", fileName, wave.sampleRate, wave.sampleSize, wave.channels);
stb_vorbis_close(oggFile);
}
@@ -1364,21 +1214,13 @@ static Wave LoadOGG(char *fileName)
return wave;
}
-// Unload Wave data
-static void UnloadWave(Wave wave)
-{
- free(wave.data);
-
- TraceLog(INFO, "Unloaded wave data");
-}
-
// Some required functions for audio standalone module version
#if defined(AUDIO_STANDALONE)
// Get the extension for a filename
const char *GetExtension(const char *fileName)
{
const char *dot = strrchr(fileName, '.');
- if(!dot || dot == fileName) return "";
+ if (!dot || dot == fileName) return "";
return (dot + 1);
}
@@ -1393,7 +1235,7 @@ void TraceLog(int msgType, const char *text, ...)
traceDebugMsgs = 0;
#endif
- switch(msgType)
+ switch (msgType)
{
case INFO: fprintf(stdout, "INFO: "); break;
case ERROR: fprintf(stdout, "ERROR: "); break;
diff --git a/src/audio.h b/src/audio.h
index b6850911..923492ca 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -2,7 +2,7 @@
*
* raylib.audio
*
-* Basic functions to manage Audio:
+* Basic functions to manage Audio:
* Manage audio device (init/close)
* Load and Unload audio files
* Play/Stop/Pause/Resume loaded audio
@@ -68,13 +68,29 @@ typedef struct Sound {
// 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
- unsigned int dataSize; // Data size in bytes
- unsigned int sampleRate; // Samples per second to be played
- short bitsPerSample; // Sample size in bits
- short channels;
} Wave;
+// Music type (file streaming from memory)
+// NOTE: Anything longer than ~10 seconds should be streamed
+typedef struct Music *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;
+
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
@@ -89,34 +105,44 @@ extern "C" { // Prevents name mangling of functions
//----------------------------------------------------------------------------------
void InitAudioDevice(void); // Initialize audio device and context
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
-bool IsAudioDeviceReady(void); // Check if device has been initialized successfully
+bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
Sound LoadSound(char *fileName); // Load sound to memory
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
+void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data
void UnloadSound(Sound sound); // Unload sound
void PlaySound(Sound sound); // Play a sound
void PauseSound(Sound sound); // Pause a sound
+void ResumeSound(Sound sound); // Resume a paused sound
void StopSound(Sound sound); // Stop playing a sound
bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
-int PlayMusicStream(int index, char *fileName); // Start music playing (open stream)
-void UpdateMusicStream(int index); // Updates buffers for music streaming
-void StopMusicStream(int index); // Stop music playing (close stream)
-void PauseMusicStream(int index); // Pause music playing
-void ResumeMusicStream(int index); // Resume playing paused music
-bool IsMusicPlaying(int index); // Check if music is playing
-void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
-void SetMusicPitch(int index, float pitch); // Set pitch for a music (1.0 is base level)
-float GetMusicTimeLength(int index); // Get music time length (in seconds)
-float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
-int GetMusicStreamCount(void); // Get number of streams loaded
-
-int InitRawMixChannel(int sampleRate, int channels, bool floatingPoint); // Initialize raw audio mix channel for audio buffering
-int BufferRawMixChannel(int mixc, void *data, unsigned short numberElements); // Buffers data directly to raw mix channel
-void CloseRawMixChannel(int mixc); // Closes and frees raw mix channel
+Music LoadMusicStream(char *fileName); // Load music stream from file
+void UnloadMusicStream(Music music); // Unload music stream
+void PlayMusicStream(Music music); // Start music playing (open stream)
+void UpdateMusicStream(Music music); // Updates buffers for music streaming
+void StopMusicStream(Music music); // Stop music playing (close stream)
+void PauseMusicStream(Music music); // Pause music playing
+void ResumeMusicStream(Music music); // Resume playing paused music
+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)
+float GetMusicTimeLength(Music music); // Get music time length (in seconds)
+float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
+
+AudioStream InitAudioStream(unsigned int sampleRate,
+ unsigned int sampleSize,
+ unsigned int channels); // Init audio stream (to stream audio pcm data)
+void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // Update audio stream buffers with data
+void CloseAudioStream(AudioStream stream); // Close audio stream and free memory
+bool IsAudioBufferProcessed(AudioStream stream); // Check if any audio stream buffers requires refill
+void PlayAudioStream(AudioStream stream); // Play audio stream
+void PauseAudioStream(AudioStream stream); // Pause audio stream
+void ResumeAudioStream(AudioStream stream); // Resume audio stream
+void StopAudioStream(AudioStream stream); // Stop audio stream
#ifdef __cplusplus
}
diff --git a/src/camera.c b/src/camera.c
deleted file mode 100644
index 11571cca..00000000
--- a/src/camera.c
+++ /dev/null
@@ -1,523 +0,0 @@
-/**********************************************************************************************
-*
-* raylib Camera System - Camera Modes Setup and Control Functions
-*
-* Copyright (c) 2015 Marc Palau and 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 CAMERA_STANDALONE // NOTE: To use the camera module as standalone lib, just uncomment this line
- // NOTE: ProcessCamera() should be reviewed to adapt inputs to other systems
-
-#if defined(CAMERA_STANDALONE)
- #include "camera.h"
-#else
- #include "raylib.h"
-#endif
-
-#include <math.h> // Required for: sqrt(), sin(), cos()
-
-//----------------------------------------------------------------------------------
-// Defines and Macros
-//----------------------------------------------------------------------------------
-// CAMERA_GENERIC
-#define CAMERA_SCROLL_SENSITIVITY 1.5f
-
-// FREE_CAMERA
-#define FREE_CAMERA_MOUSE_SENSITIVITY 0.01f
-#define FREE_CAMERA_DISTANCE_MIN_CLAMP 0.3f
-#define FREE_CAMERA_DISTANCE_MAX_CLAMP 120.0f
-#define FREE_CAMERA_MIN_CLAMP 85.0f
-#define FREE_CAMERA_MAX_CLAMP -85.0f
-#define FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY 0.05f
-#define FREE_CAMERA_PANNING_DIVIDER 5.1f
-
-// ORBITAL_CAMERA
-#define ORBITAL_CAMERA_SPEED 0.01f
-
-// FIRST_PERSON
-//#define FIRST_PERSON_MOUSE_SENSITIVITY 0.003f
-#define FIRST_PERSON_FOCUS_DISTANCE 25.0f
-#define FIRST_PERSON_MIN_CLAMP 85.0f
-#define FIRST_PERSON_MAX_CLAMP -85.0f
-
-#define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0f
-#define FIRST_PERSON_STEP_DIVIDER 30.0f
-#define FIRST_PERSON_WAVING_DIVIDER 200.0f
-
-#define FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85f
-
-// THIRD_PERSON
-//#define THIRD_PERSON_MOUSE_SENSITIVITY 0.003f
-#define THIRD_PERSON_DISTANCE_CLAMP 1.2f
-#define THIRD_PERSON_MIN_CLAMP 5.0f
-#define THIRD_PERSON_MAX_CLAMP -85.0f
-#define THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f }
-
-// PLAYER (used by camera)
-#define PLAYER_WIDTH 0.4f
-#define PLAYER_HEIGHT 0.9f
-#define PLAYER_DEPTH 0.4f
-#define PLAYER_MOVEMENT_DIVIDER 20.0f
-
-//----------------------------------------------------------------------------------
-// Types and Structures Definition
-//----------------------------------------------------------------------------------
-// Camera move modes (first person and third person cameras)
-typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_DOWN } CameraMove;
-
-//----------------------------------------------------------------------------------
-// Global Variables Definition
-//----------------------------------------------------------------------------------
-static Camera internalCamera = {{ 2.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f };
-static Vector2 cameraAngle = { 0.0f, 0.0f };
-static float cameraTargetDistance = 5.0f;
-static Vector2 cameraMousePosition = { 0.0f, 0.0f };
-static Vector2 cameraMouseVariation = { 0.0f, 0.0f };
-static float mouseSensitivity = 0.003f;
-static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' };
-static int cameraMoveCounter = 0;
-static int cameraUseGravity = 1;
-static int panControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON
-static int altControlKey = 342; // raylib: KEY_LEFT_ALT
-static int smoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL
-
-static int cameraMode = CAMERA_CUSTOM;
-
-//----------------------------------------------------------------------------------
-// Module specific Functions Declaration
-//----------------------------------------------------------------------------------
-static void ProcessCamera(Camera *camera, Vector3 *playerPosition);
-
-#if defined(CAMERA_STANDALONE)
-// NOTE: Camera controls depend on some raylib input functions
-// TODO: Set your own input functions (used in ProcessCamera())
-static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
-static void SetMousePosition(Vector2 pos) {}
-static int IsMouseButtonDown(int button) { return 0;}
-static int GetMouseWheelMove() { return 0; }
-static int GetScreenWidth() { return 1280; }
-static int GetScreenHeight() { return 720; }
-static void ShowCursor() {}
-static void HideCursor() {}
-static int IsKeyDown(int key) { return 0; }
-#endif
-
-//----------------------------------------------------------------------------------
-// Module Functions Definition
-//----------------------------------------------------------------------------------
-
-// Select camera mode (multiple camera modes available)
-// TODO: Review hardcoded values when changing modes...
-void SetCameraMode(int mode)
-{
- if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE))
- {
- cameraMode = CAMERA_THIRD_PERSON;
- cameraTargetDistance = 5.0f;
- cameraAngle.y = -40*DEG2RAD;
- ProcessCamera(&internalCamera, &internalCamera.position);
- }
- else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL))
- {
- cameraMode = CAMERA_THIRD_PERSON;
- cameraTargetDistance = 5.0f;
- cameraAngle.y = -40*DEG2RAD;
- ProcessCamera(&internalCamera, &internalCamera.position);
- }
- else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE))
- {
- cameraTargetDistance = 10.0f;
- cameraAngle.x = 45*DEG2RAD;
- cameraAngle.y = -40*DEG2RAD;
- internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
- ProcessCamera(&internalCamera, &internalCamera.position);
-
- ShowCursor();
- }
- else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL))
- {
- cameraTargetDistance = 10.0f;
- cameraAngle.x = 225*DEG2RAD;
- cameraAngle.y = -40*DEG2RAD;
- internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f };
- ProcessCamera(&internalCamera, &internalCamera.position);
- }
-
- cameraMode = mode;
-}
-
-// Update camera (player position is ignored)
-void UpdateCamera(Camera *camera)
-{
- Vector3 position = { 0.0f, 0.0f, 0.0f };
-
- // Process internal camera and player position (if required)
- if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, &position);
-
- *camera = internalCamera;
-}
-
-// Update camera and player position (1st person and 3rd person cameras)
-void UpdateCameraPlayer(Camera *camera, Vector3 *position)
-{
- // Process internal camera and player position (if required)
- if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position);
-
- *camera = internalCamera;
-}
-
-// Set internal camera position
-void SetCameraPosition(Vector3 position)
-{
- internalCamera.position = position;
-
- Vector3 v1 = internalCamera.position;
- Vector3 v2 = internalCamera.target;
-
- float dx = v2.x - v1.x;
- float dy = v2.y - v1.y;
- float dz = v2.z - v1.z;
-
- cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz);
-}
-
-// Set internal camera target
-void SetCameraTarget(Vector3 target)
-{
- internalCamera.target = target;
-
- Vector3 v1 = internalCamera.position;
- Vector3 v2 = internalCamera.target;
-
- float dx = v2.x - v1.x;
- float dy = v2.y - v1.y;
- float dz = v2.z - v1.z;
-
- cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz);
-}
-
-// Set internal camera fovy
-void SetCameraFovy(float fovy)
-{
- internalCamera.fovy = fovy;
-}
-
-// Set camera pan key to combine with mouse movement (free camera)
-void SetCameraPanControl(int panKey)
-{
- panControlKey = panKey;
-}
-
-// Set camera alt key to combine with mouse movement (free camera)
-void SetCameraAltControl(int altKey)
-{
- altControlKey = altKey;
-}
-
-// Set camera smooth zoom key to combine with mouse (free camera)
-void SetCameraSmoothZoomControl(int szKey)
-{
- smoothZoomControlKey = szKey;
-}
-
-// Set camera move controls (1st person and 3rd person cameras)
-void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey)
-{
- cameraMoveControl[MOVE_FRONT] = frontKey;
- cameraMoveControl[MOVE_LEFT] = leftKey;
- cameraMoveControl[MOVE_BACK] = backKey;
- cameraMoveControl[MOVE_RIGHT] = rightKey;
- cameraMoveControl[MOVE_UP] = upKey;
- cameraMoveControl[MOVE_DOWN] = downKey;
-}
-
-// Set camera mouse sensitivity (1st person and 3rd person cameras)
-void SetCameraMouseSensitivity(float sensitivity)
-{
- mouseSensitivity = (sensitivity/10000.0f);
-}
-
-//----------------------------------------------------------------------------------
-// Module specific Functions Definition
-//----------------------------------------------------------------------------------
-
-// Process desired camera mode and controls
-// NOTE: Camera controls depend on some raylib functions:
-// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove()
-// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor()
-// Keys: IsKeyDown()
-static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
-{
- // Mouse movement detection
- Vector2 mousePosition = GetMousePosition();
- int mouseWheelMove = GetMouseWheelMove();
- int panKey = IsMouseButtonDown(panControlKey); // bool value
-
- int screenWidth = GetScreenWidth();
- int screenHeight = GetScreenHeight();
-
- if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL))
- {
- HideCursor();
-
- if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y});
- else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3});
- else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y});
- else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3});
- else
- {
- cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x;
- cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y;
- }
- }
- else
- {
- ShowCursor();
-
- cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x;
- cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y;
- }
-
- // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call
- // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON
- cameraMousePosition = GetMousePosition();
-
- // Support for multiple automatic camera modes
- switch (cameraMode)
- {
- case CAMERA_FREE:
- {
- // Camera zoom
- if ((cameraTargetDistance < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
- {
- cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
-
- if (cameraTargetDistance > FREE_CAMERA_DISTANCE_MAX_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MAX_CLAMP;
- }
- // Camera looking down
- else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
- {
- camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- }
- else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0))
- {
- camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
-
- // if (camera->target.y < 0) camera->target.y = -0.001;
- }
- else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0))
- {
- cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
- if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP;
- }
- // Camera looking up
- else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
- {
- camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- }
- else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0))
- {
- camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
- camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
-
- // if (camera->target.y > 0) camera->target.y = 0.001;
- }
- else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0))
- {
- cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
- if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP;
- }
-
- // Inputs
- if (IsKeyDown(altControlKey))
- {
- if (IsKeyDown(smoothZoomControlKey))
- {
- // Camera smooth zoom
- if (panKey) cameraTargetDistance += (cameraMouseVariation.y*FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY);
- }
- // Camera orientation calculation
- else if (panKey)
- {
- // Camera orientation calculation
- // Get the mouse sensitivity
- cameraAngle.x += cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY;
- cameraAngle.y += cameraMouseVariation.y*-FREE_CAMERA_MOUSE_SENSITIVITY;
-
- // Angle clamp
- if (cameraAngle.y > FREE_CAMERA_MIN_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MIN_CLAMP*DEG2RAD;
- else if (cameraAngle.y < FREE_CAMERA_MAX_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MAX_CLAMP*DEG2RAD;
- }
- }
- // Paning
- else if (panKey)
- {
- camera->target.x += ((cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER);
- camera->target.y += ((cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER);
- camera->target.z += ((cameraMouseVariation.x*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER);
- }
-
- // Focus to center
- // TODO: Move this function out of this module?
- if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f };
-
- // Camera position update
- camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
-
- if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
- else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
-
- camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
-
- } break;
- case CAMERA_ORBITAL:
- {
- cameraAngle.x += ORBITAL_CAMERA_SPEED;
-
- // Camera zoom
- cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
-
- // Camera distance clamp
- if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
-
- // Focus to center
- if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f };
-
- // Camera position update
- camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
-
- if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
- else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
-
- camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
-
- } break;
- case CAMERA_FIRST_PERSON:
- case CAMERA_THIRD_PERSON:
- {
- bool isMoving = false;
-
- // Keyboard inputs
- if (IsKeyDown(cameraMoveControl[MOVE_FRONT]))
- {
- playerPosition->x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
- playerPosition->z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
-
- if (!cameraUseGravity) camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER;
-
- isMoving = true;
- }
- else if (IsKeyDown(cameraMoveControl[MOVE_BACK]))
- {
- playerPosition->x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
- playerPosition->z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
-
- if (!cameraUseGravity) camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER;
-
- isMoving = true;
- }
-
- if (IsKeyDown(cameraMoveControl[MOVE_LEFT]))
- {
- playerPosition->x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
- playerPosition->z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
-
- isMoving = true;
- }
- else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT]))
- {
- playerPosition->x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
- playerPosition->z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER;
-
- isMoving = true;
- }
-
- if (IsKeyDown(cameraMoveControl[MOVE_UP]))
- {
- if (!cameraUseGravity) playerPosition->y += 1.0f/PLAYER_MOVEMENT_DIVIDER;
- }
- else if (IsKeyDown(cameraMoveControl[MOVE_DOWN]))
- {
- if (!cameraUseGravity) playerPosition->y -= 1.0f/PLAYER_MOVEMENT_DIVIDER;
- }
-
- if (cameraMode == CAMERA_THIRD_PERSON)
- {
- // Camera orientation calculation
- cameraAngle.x += cameraMouseVariation.x*-mouseSensitivity;
- cameraAngle.y += cameraMouseVariation.y*-mouseSensitivity;
-
- // Angle clamp
- if (cameraAngle.y > THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MIN_CLAMP*DEG2RAD;
- else if (cameraAngle.y < THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MAX_CLAMP*DEG2RAD;
-
- // Camera zoom
- cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
-
- // Camera distance clamp
- if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
-
- // Camera is always looking at player
- camera->target.x = playerPosition->x + THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x);
- camera->target.y = playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + THIRD_PERSON_OFFSET.y;
- camera->target.z = playerPosition->z + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - THIRD_PERSON_OFFSET.x*sin(cameraAngle.x);
-
- // Camera position update
- camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
-
- if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
- else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
-
- camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
- }
- else // CAMERA_FIRST_PERSON
- {
- if (isMoving) cameraMoveCounter++;
-
- // Camera orientation calculation
- cameraAngle.x += (cameraMouseVariation.x * -mouseSensitivity);
- cameraAngle.y += (cameraMouseVariation.y * -mouseSensitivity);
-
- // Angle clamp
- if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP*DEG2RAD;
- else if (cameraAngle.y < FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MAX_CLAMP*DEG2RAD;
-
- // Camera is always looking at player
- camera->target.x = camera->position.x - sin(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE;
- camera->target.y = camera->position.y + sin(cameraAngle.y)*FIRST_PERSON_FOCUS_DISTANCE;
- camera->target.z = camera->position.z - cos(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE;
-
- camera->position.x = playerPosition->x;
- camera->position.y = (playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMoveCounter/FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/FIRST_PERSON_STEP_DIVIDER;
- camera->position.z = playerPosition->z;
-
- camera->up.x = sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER;
- camera->up.z = -sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER;
- }
- } break;
- default: break;
- }
-}
diff --git a/src/camera.h b/src/camera.h
index 8d8029af..33220390 100644
--- a/src/camera.h
+++ b/src/camera.h
@@ -2,7 +2,19 @@
*
* raylib Camera System - Camera Modes Setup and Control Functions
*
-* Copyright (c) 2015 Marc Palau and Ramon Santamaria
+* #define CAMERA_IMPLEMENTATION
+* Generates the implementation of the library into the included file.
+* If not defined, the library is in header only mode and can be included in other headers
+* or source files without problems. But only ONE file should hold the implementation.
+*
+* #define CAMERA_STANDALONE
+* If defined, the library can be used as standalone as a camera system but some
+* functions must be redefined to manage inputs accordingly.
+*
+* NOTE: Memory footprint of this library is aproximately 52 bytes (global variables)
+*
+* Initial design by Marc Palau (2014)
+* Reviewed by Ramon Santamaria (2015-2016)
*
* 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,13 +36,6 @@
#ifndef CAMERA_H
#define CAMERA_H
-#ifndef PI
- #define PI 3.14159265358979323846
-#endif
-
-#define DEG2RAD (PI/180.0f)
-#define RAD2DEG (180.0f/PI)
-
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -40,28 +45,37 @@
// Types and Structures Definition
// NOTE: Below types are required for CAMERA_STANDALONE usage
//----------------------------------------------------------------------------------
-// Camera modes
-typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
-
-// Vector2 type
-typedef struct Vector2 {
- float x;
- float y;
-} Vector2;
-
-// Vector3 type
-typedef struct Vector3 {
- float x;
- float y;
- float z;
-} Vector3;
-
-// Camera type, defines a camera position/orientation in 3d space
-typedef struct Camera {
- Vector3 position;
- Vector3 target;
- Vector3 up;
-} Camera;
+#if defined(CAMERA_STANDALONE)
+ // Camera modes
+ typedef enum {
+ CAMERA_CUSTOM = 0,
+ CAMERA_FREE,
+ CAMERA_ORBITAL,
+ CAMERA_FIRST_PERSON,
+ CAMERA_THIRD_PERSON
+ } CameraMode;
+
+ // Vector2 type
+ typedef struct Vector2 {
+ float x;
+ float y;
+ } Vector2;
+
+ // Vector3 type
+ typedef struct Vector3 {
+ float x;
+ float y;
+ float z;
+ } Vector3;
+
+ // Camera type, defines a camera position/orientation in 3d space
+ typedef struct Camera {
+ Vector3 position;
+ Vector3 target;
+ Vector3 up;
+ float fovy;
+ } Camera;
+#endif
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
@@ -75,25 +89,415 @@ extern "C" { // Prevents name mangling of functions
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
-void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
-void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
-void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
-
-void SetCameraPosition(Vector3 position); // Set internal camera position
-void SetCameraTarget(Vector3 target); // Set internal camera target
-void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
+#if defined(CAMERA_STANDALONE)
+void SetCameraMode(Camera camera, int mode); // Set camera mode (multiple camera modes available)
+void UpdateCamera(Camera *camera); // Update camera position for selected mode
void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
-
void SetCameraMoveControls(int frontKey, int backKey,
- int leftKey, int rightKey,
+ int rightKey, int leftKey,
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
-void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
+#endif
#ifdef __cplusplus
}
#endif
#endif // CAMERA_H
+
+
+/***********************************************************************************
+*
+* CAMERA IMPLEMENTATION
+*
+************************************************************************************/
+
+#if defined(CAMERA_IMPLEMENTATION)
+
+#include <math.h> // Required for: sqrt(), sin(), cos()
+
+#ifndef PI
+ #define PI 3.14159265358979323846
+#endif
+
+#ifndef DEG2RAD
+ #define DEG2RAD (PI/180.0f)
+#endif
+
+#ifndef RAD2DEG
+ #define RAD2DEG (180.0f/PI)
+#endif
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+// Camera mouse movement sensitivity
+#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f
+#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f
+
+// FREE_CAMERA
+#define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f
+#define CAMERA_FREE_DISTANCE_MIN_CLAMP 0.3f
+#define CAMERA_FREE_DISTANCE_MAX_CLAMP 120.0f
+#define CAMERA_FREE_MIN_CLAMP 85.0f
+#define CAMERA_FREE_MAX_CLAMP -85.0f
+#define CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY 0.05f
+#define CAMERA_FREE_PANNING_DIVIDER 5.1f
+
+// ORBITAL_CAMERA
+#define CAMERA_ORBITAL_SPEED 0.01f // Radians per frame
+
+// FIRST_PERSON
+//#define CAMERA_FIRST_PERSON_MOUSE_SENSITIVITY 0.003f
+#define CAMERA_FIRST_PERSON_FOCUS_DISTANCE 25.0f
+#define CAMERA_FIRST_PERSON_MIN_CLAMP 85.0f
+#define CAMERA_FIRST_PERSON_MAX_CLAMP -85.0f
+
+#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0f
+#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f
+#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f
+
+// THIRD_PERSON
+//#define CAMERA_THIRD_PERSON_MOUSE_SENSITIVITY 0.003f
+#define CAMERA_THIRD_PERSON_DISTANCE_CLAMP 1.2f
+#define CAMERA_THIRD_PERSON_MIN_CLAMP 5.0f
+#define CAMERA_THIRD_PERSON_MAX_CLAMP -85.0f
+#define CAMERA_THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f }
+
+// PLAYER (used by camera)
+#define PLAYER_MOVEMENT_SENSITIVITY 20.0f
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+// Camera move modes (first person and third person cameras)
+typedef enum { MOVE_FRONT = 0, MOVE_BACK, MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_DOWN } CameraMove;
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+static Vector2 cameraAngle = { 0.0f, 0.0f }; // TODO: Remove! Compute it in UpdateCamera()
+static float cameraTargetDistance = 0.0f; // TODO: Remove! Compute it in UpdateCamera()
+static float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters)
+
+static int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' };
+static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON
+static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT
+static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL
+
+static int cameraMode = CAMERA_CUSTOM; // Current camera mode
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Declaration
+//----------------------------------------------------------------------------------
+#if defined(CAMERA_STANDALONE)
+// NOTE: Camera controls depend on some raylib input functions
+// TODO: Set your own input functions (used in UpdateCamera())
+static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
+static void SetMousePosition(Vector2 pos) {}
+static int IsMouseButtonDown(int button) { return 0;}
+static int GetMouseWheelMove() { return 0; }
+static int GetScreenWidth() { return 1280; }
+static int GetScreenHeight() { return 720; }
+static void ShowCursor() {}
+static void HideCursor() {}
+static int IsKeyDown(int key) { return 0; }
+#endif
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition
+//----------------------------------------------------------------------------------
+
+// Select camera mode (multiple camera modes available)
+void SetCameraMode(Camera camera, int mode)
+{
+ // TODO: cameraTargetDistance and cameraAngle should be
+ // calculated using camera parameters on UpdateCamera()
+
+ Vector3 v1 = camera.position;
+ Vector3 v2 = camera.target;
+
+ float dx = v2.x - v1.x;
+ float dy = v2.y - v1.y;
+ float dz = v2.z - v1.z;
+
+ cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz);
+
+ Vector2 distance = { 0.0f, 0.0f };
+ distance.x = sqrt(dx*dx + dz*dz);
+ distance.y = sqrt(dx*dx + dy*dy);
+
+ // Camera angle calculation
+ cameraAngle.x = asin(fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
+ cameraAngle.y = -asin(fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW)
+
+ // NOTE: Just testing what cameraAngle means
+ //cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
+ //cameraAngle.y = -60.0f*DEG2RAD; // Camera angle in plane XY (0 aligned with X, move positive CW)
+
+ playerEyesPosition = camera.position.y;
+
+ cameraMode = mode;
+}
+
+// Update camera depending on selected mode
+// NOTE: Camera controls depend on some raylib functions:
+// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove()
+// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor()
+// Keys: IsKeyDown()
+// TODO: Port to quaternion-based camera
+void UpdateCamera(Camera *camera)
+{
+ static int swingCounter = 0; // Used for 1st person swinging movement
+ static Vector2 previousMousePosition = { 0.0f, 0.0f };
+
+ // TODO: Compute cameraTargetDistance and cameraAngle here
+
+ // Mouse movement detection
+ Vector2 mousePositionDelta = { 0.0f, 0.0f };
+ Vector2 mousePosition = GetMousePosition();
+ int mouseWheelMove = GetMouseWheelMove();
+
+ // Keys input detection
+ bool panKey = IsMouseButtonDown(cameraPanControlKey);
+ bool altKey = IsKeyDown(cameraAltControlKey);
+ bool szoomKey = IsKeyDown(cameraSmoothZoomControlKey);
+
+ bool direction[6] = { IsKeyDown(cameraMoveControl[MOVE_FRONT]),
+ IsKeyDown(cameraMoveControl[MOVE_BACK]),
+ IsKeyDown(cameraMoveControl[MOVE_RIGHT]),
+ IsKeyDown(cameraMoveControl[MOVE_LEFT]),
+ IsKeyDown(cameraMoveControl[MOVE_UP]),
+ IsKeyDown(cameraMoveControl[MOVE_DOWN]) };
+
+ // TODO: Consider touch inputs for camera
+
+ if (cameraMode != CAMERA_CUSTOM)
+ {
+ // Get screen size
+ int screenWidth = GetScreenWidth();
+ int screenHeight = GetScreenHeight();
+
+ if ((cameraMode == CAMERA_FIRST_PERSON) ||
+ (cameraMode == CAMERA_THIRD_PERSON))
+ {
+ HideCursor();
+
+ if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y });
+ else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 });
+ else if (mousePosition.x > (screenWidth - screenHeight/3)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y });
+ else if (mousePosition.y > (screenHeight - screenHeight/3)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 });
+ else
+ {
+ mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
+ mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
+ }
+ }
+ else // CAMERA_FREE, CAMERA_ORBITAL
+ {
+ ShowCursor();
+
+ mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
+ mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
+ }
+
+ // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call
+ // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON
+ previousMousePosition = GetMousePosition();
+ }
+
+ // Support for multiple automatic camera modes
+ switch (cameraMode)
+ {
+ case CAMERA_FREE:
+ {
+ // Camera zoom
+ if ((cameraTargetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
+ {
+ cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
+
+ if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
+ }
+ // Camera looking down
+ else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
+ {
+ camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ }
+ else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0))
+ {
+ camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+
+ // if (camera->target.y < 0) camera->target.y = -0.001;
+ }
+ else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0))
+ {
+ cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
+ if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
+ }
+ // Camera looking up
+ else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
+ {
+ camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ }
+ else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0))
+ {
+ camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+ camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
+
+ // if (camera->target.y > 0) camera->target.y = 0.001;
+ }
+ else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0))
+ {
+ cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
+ if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
+ }
+
+ // Input keys checks
+ if (panKey)
+ {
+ if (altKey) // Alternative key behaviour
+ {
+ if (szoomKey)
+ {
+ // Camera smooth zoom
+ cameraTargetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY);
+ }
+ else
+ {
+ // Camera rotation
+ cameraAngle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY;
+ cameraAngle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY;
+
+ // Angle clamp
+ if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD;
+ else if (cameraAngle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD;
+ }
+ }
+ else
+ {
+ // Camera panning
+ camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
+ camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
+ camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
+ }
+ }
+
+ } break;
+ case CAMERA_ORBITAL:
+ {
+ cameraAngle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle
+ cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom
+
+ // Camera distance clamp
+ if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
+
+ } break;
+ case CAMERA_FIRST_PERSON:
+ case CAMERA_THIRD_PERSON:
+ {
+ camera->position.x += (sin(cameraAngle.x)*direction[MOVE_BACK] -
+ sin(cameraAngle.x)*direction[MOVE_FRONT] -
+ cos(cameraAngle.x)*direction[MOVE_LEFT] +
+ cos(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
+
+ camera->position.y += (sin(cameraAngle.y)*direction[MOVE_FRONT] -
+ sin(cameraAngle.y)*direction[MOVE_BACK] +
+ 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
+
+ camera->position.z += (cos(cameraAngle.x)*direction[MOVE_BACK] -
+ cos(cameraAngle.x)*direction[MOVE_FRONT] +
+ sin(cameraAngle.x)*direction[MOVE_LEFT] -
+ sin(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
+
+ bool isMoving = false; // Required for swinging
+
+ for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; }
+
+ // Camera orientation calculation
+ cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
+ cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
+
+ if (cameraMode == CAMERA_THIRD_PERSON)
+ {
+ // Angle clamp
+ if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD;
+ else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
+
+ // Camera zoom
+ cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
+
+ // Camera distance clamp
+ if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
+
+ // Camera is always looking at player
+ camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x);
+ camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y;
+ camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x);
+ }
+ else // CAMERA_FIRST_PERSON
+ {
+ // Angle clamp
+ if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
+ else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
+
+ // Camera is always looking at player
+ camera->target.x = camera->position.x - sin(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
+ camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
+ camera->target.z = camera->position.z - cos(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
+
+ if (isMoving) swingCounter++;
+
+ // Camera position update
+ // NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
+ camera->position.y = playerEyesPosition - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
+
+ camera->up.x = sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
+ camera->up.z = -sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
+ }
+ } break;
+ default: break;
+ }
+
+ // Update camera position with changes
+ if ((cameraMode == CAMERA_FREE) ||
+ (cameraMode == CAMERA_ORBITAL) ||
+ (cameraMode == CAMERA_THIRD_PERSON))
+ {
+ // TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target...
+ camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
+ if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
+ else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
+ camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
+ }
+}
+
+// Set camera pan key to combine with mouse movement (free camera)
+void SetCameraPanControl(int panKey) { cameraPanControlKey = panKey; }
+
+// Set camera alt key to combine with mouse movement (free camera)
+void SetCameraAltControl(int altKey) { cameraAltControlKey = altKey; }
+
+// Set camera smooth zoom key to combine with mouse (free camera)
+void SetCameraSmoothZoomControl(int szKey) { cameraSmoothZoomControlKey = szKey; }
+
+// Set camera move controls (1st person and 3rd person cameras)
+void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey)
+{
+ cameraMoveControl[MOVE_FRONT] = frontKey;
+ cameraMoveControl[MOVE_BACK] = backKey;
+ cameraMoveControl[MOVE_RIGHT] = rightKey;
+ cameraMoveControl[MOVE_LEFT] = leftKey;
+ cameraMoveControl[MOVE_UP] = upKey;
+ cameraMoveControl[MOVE_DOWN] = downKey;
+}
+
+#endif // CAMERA_IMPLEMENTATION
diff --git a/src/core.c b/src/core.c
index a3253d79..0db1c573 100644
--- a/src/core.c
+++ b/src/core.c
@@ -39,13 +39,20 @@
#include "raylib.h" // raylib main header
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
-#include "utils.h" // TraceLog() function
- // NOTE: Includes Android fopen map, InitAssetManager()
-
+#include "utils.h" // Includes Android fopen map, InitAssetManager(), TraceLog()
+
#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
+#define GESTURES_IMPLEMENTATION
+#include "gestures.h" // Gestures detection functionality
+
+#if !defined(PLATFORM_ANDROID)
+ #define CAMERA_IMPLEMENTATION
+ #include "camera.h" // Camera system functionality
+#endif
+
#include <stdio.h> // Standard input / output lib
#include <stdlib.h> // Declares malloc() and free() for memory management, rand(), atexit()
#include <stdint.h> // Required for typedef unsigned long long int uint64_t, used by hi-res timer
@@ -115,9 +122,9 @@
//#define DEFAULT_KEYBOARD_DEV "/dev/input/eventN"
//#define DEFAULT_MOUSE_DEV "/dev/input/eventN"
//#define DEFAULT_GAMEPAD_DEV "/dev/input/eventN"
-
+
#define MOUSE_SENSITIVITY 0.8f
-
+
#define MAX_GAMEPADS 2 // Max number of gamepads supported
#define MAX_GAMEPAD_BUTTONS 11 // Max bumber of buttons supported (per gamepad)
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
@@ -234,6 +241,9 @@ static bool showLogo = false; // Track if showing logo at init is
extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow()
extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory
+extern void ProcessGestureEvent(GestureEvent event); // [Module: gestures] Process gesture event and translate it into gestures
+extern void UpdateGestures(void); // [Module: gestures] Update gestures detected (called in PollInputEvents())
+
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
@@ -293,7 +303,7 @@ static void *GamepadThread(void *arg); // Mouse reading thread
// Initialize Window and Graphics Context (OpenGL)
void InitWindow(int width, int height, const char *title)
{
- TraceLog(INFO, "Initializing raylib (v1.5.0)");
+ TraceLog(INFO, "Initializing raylib (v1.6.0)");
// Store window title (could be useful...)
windowTitle = title;
@@ -325,7 +335,7 @@ void InitWindow(int width, int height, const char *title)
emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback);
emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback);
emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback);
-
+
// TODO: Add gamepad support (not provided by GLFW3 on emscripten)
//emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenInputCallback);
//emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenInputCallback);
@@ -347,7 +357,7 @@ void InitWindow(int width, int height, const char *title)
// Android activity initialization
void InitWindow(int width, int height, struct android_app *state)
{
- TraceLog(INFO, "Initializing raylib (v1.5.0)");
+ TraceLog(INFO, "Initializing raylib (v1.6.0)");
app_dummy();
@@ -386,7 +396,7 @@ void InitWindow(int width, int height, struct android_app *state)
//state->userData = &engine;
app->onAppCmd = AndroidCommandCallback;
app->onInputEvent = AndroidInputCallback;
-
+
InitAssetManager(app->activity->assetManager);
TraceLog(INFO, "Android app initialized successfully");
@@ -439,7 +449,7 @@ void CloseWindow(void)
eglTerminate(display);
display = EGL_NO_DISPLAY;
- }
+ }
#endif
#if defined(PLATFORM_RPI)
@@ -519,7 +529,7 @@ void BeginDrawing(void)
currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called
updateTime = currentTime - previousTime;
previousTime = currentTime;
-
+
rlClearScreenBuffers(); // Clear current framebuffers
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
rlMultMatrixf(MatrixToFloat(downscaleView)); // If downscale required, apply it here
@@ -535,7 +545,7 @@ void EndDrawing(void)
SwapBuffers(); // Copy back buffer to front buffer
PollInputEvents(); // Poll user events
-
+
// Frame time control system
currentTime = GetTime();
drawTime = currentTime - previousTime;
@@ -567,9 +577,9 @@ void Begin2dMode(Camera2D camera)
Matrix matRotation = MatrixRotate((Vector3){ 0.0f, 0.0f, 1.0f }, camera.rotation*DEG2RAD);
Matrix matScale = MatrixScale(camera.zoom, camera.zoom, 1.0f);
Matrix matTranslation = MatrixTranslate(camera.offset.x + camera.target.x, camera.offset.y + camera.target.y, 0.0f);
-
+
Matrix matTransform = MatrixMultiply(MatrixMultiply(matOrigin, MatrixMultiply(matScale, matRotation)), matTranslation);
-
+
rlMultMatrixf(MatrixToFloat(matTransform));
}
@@ -585,14 +595,14 @@ void End2dMode(void)
void Begin3dMode(Camera camera)
{
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
-
+
if (IsVrDeviceReady()) BeginVrDrawing();
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
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*PI/360.0);
@@ -607,15 +617,15 @@ void Begin3dMode(Camera camera)
// Setup Camera view
Matrix cameraView = MatrixLookAt(camera.position, camera.target, camera.up);
rlMultMatrixf(MatrixToFloat(cameraView)); // Multiply MODELVIEW matrix by view matrix (camera)
-
+
rlEnableDepthTest(); // Enable DEPTH_TEST for 3D
}
// Ends 3D mode and returns to default 2D orthographic mode
void End3dMode(void)
-{
+{
rlglDraw(); // Process internal buffers (update + draw)
-
+
if (IsVrDeviceReady()) EndVrDrawing();
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
@@ -625,7 +635,7 @@ void End3dMode(void)
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
//rlTranslatef(0.375, 0.375, 0); // HACK to ensure pixel-perfect drawing on OpenGL (after exiting 3D mode)
-
+
rlDisableDepthTest(); // Disable DEPTH_TEST for 2D
}
@@ -637,16 +647,16 @@ void BeginTextureMode(RenderTexture2D target)
rlEnableRenderTexture(target.id); // Enable render target
rlClearScreenBuffers(); // Clear render texture buffers
-
+
// Set viewport to framebuffer size
- rlViewport(0, 0, target.texture.width, target.texture.height);
-
+ rlViewport(0, 0, target.texture.width, target.texture.height);
+
rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix
rlLoadIdentity(); // Reset current matrix (PROJECTION)
// Set orthographic projection to current framebuffer size
// NOTE: Configured top-left corner as (0, 0)
- rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f);
+ rlOrtho(0, target.texture.width, target.texture.height, 0, 0.0f, 1.0f);
rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
@@ -664,10 +674,10 @@ void EndTextureMode(void)
// Set viewport to default framebuffer size (screen size)
// TODO: consider possible viewport offsets
rlViewport(0, 0, GetScreenWidth(), GetScreenHeight());
-
+
rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix
rlLoadIdentity(); // Reset current matrix (PROJECTION)
-
+
// Set orthographic projection to current framebuffer size
// NOTE: Configured top-left corner as (0, 0)
rlOrtho(0, GetScreenWidth(), GetScreenHeight(), 0, 0.0f, 1.0f);
@@ -679,7 +689,8 @@ void EndTextureMode(void)
// Set target FPS for the game
void SetTargetFPS(int fps)
{
- targetTime = 1.0/(double)fps;
+ if (fps < 1) targetTime = 0.0;
+ else targetTime = 1.0/(double)fps;
TraceLog(INFO, "Target time per frame: %02.03f milliseconds", (float)targetTime*1000);
}
@@ -693,7 +704,7 @@ float GetFPS(void)
// Returns time in seconds for one frame
float GetFrameTime(void)
{
- // As we are operate quite a lot with frameTime,
+ // As we are operate quite a lot with frameTime,
// it could be no stable, so we round it before passing it around
// NOTE: There are still problems with high framerates (>500fps)
double roundedFrameTime = round(frameTime*10000)/10000.0;
@@ -727,7 +738,7 @@ float *VectorToFloat(Vector3 vec)
}
// Converts Matrix to float array
-// NOTE: Returned vector is a transposed version of the Matrix struct,
+// NOTE: Returned vector is a transposed version of the Matrix struct,
// it should be this way because, despite raymath use OpenGL column-major convention,
// Matrix struct memory alignment and variables naming are not coherent
float *MatrixToFloat(Matrix mat)
@@ -791,7 +802,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};
@@ -833,9 +844,9 @@ void ClearDroppedFiles(void)
if (dropFilesCount > 0)
{
for (int i = 0; i < dropFilesCount; i++) free(dropFilesPath[i]);
-
+
free(dropFilesPath);
-
+
dropFilesCount = 0;
}
}
@@ -846,7 +857,7 @@ void ClearDroppedFiles(void)
void StorageSaveValue(int position, int value)
{
FILE *storageFile = NULL;
-
+
char path[128];
#if defined(PLATFORM_ANDROID)
strcpy(path, internalDataPath);
@@ -857,7 +868,7 @@ void StorageSaveValue(int position, int value)
#endif
// Try open existing file to append data
- storageFile = fopen(path, "rb+");
+ storageFile = fopen(path, "rb+");
// If file doesn't exist, create a new storage data file
if (!storageFile) storageFile = fopen(path, "wb");
@@ -869,14 +880,14 @@ void StorageSaveValue(int position, int value)
fseek(storageFile, 0, SEEK_END);
int fileSize = ftell(storageFile); // Size in bytes
fseek(storageFile, 0, SEEK_SET);
-
+
if (fileSize < (position*4)) TraceLog(WARNING, "Storage position could not be found");
else
{
fseek(storageFile, (position*4), SEEK_SET);
fwrite(&value, 1, 4, storageFile);
}
-
+
fclose(storageFile);
}
}
@@ -886,7 +897,7 @@ void StorageSaveValue(int position, int value)
int StorageLoadValue(int position)
{
int value = 0;
-
+
char path[128];
#if defined(PLATFORM_ANDROID)
strcpy(path, internalDataPath);
@@ -895,9 +906,9 @@ int StorageLoadValue(int position)
#else
strcpy(path, STORAGE_FILENAME);
#endif
-
+
// Try open existing file to append data
- FILE *storageFile = fopen(path, "rb");
+ FILE *storageFile = fopen(path, "rb");
if (!storageFile) TraceLog(WARNING, "Storage data file could not be found");
else
@@ -906,42 +917,42 @@ int StorageLoadValue(int position)
fseek(storageFile, 0, SEEK_END);
int fileSize = ftell(storageFile); // Size in bytes
rewind(storageFile);
-
+
if (fileSize < (position*4)) TraceLog(WARNING, "Storage position could not be found");
else
{
fseek(storageFile, (position*4), SEEK_SET);
fread(&value, 1, 4, storageFile);
}
-
+
fclose(storageFile);
}
-
+
return value;
}
// Returns a ray trace from mouse position
Ray GetMouseRay(Vector2 mousePosition, Camera camera)
-{
+{
Ray ray;
-
+
// Calculate normalized device coordinates
// NOTE: y value is negative
float x = (2.0f*mousePosition.x)/(float)GetScreenWidth() - 1.0f;
float y = 1.0f - (2.0f*mousePosition.y)/(float)GetScreenHeight();
float z = 1.0f;
-
+
// Store values in a vector
Vector3 deviceCoords = { x, y, z };
-
+
TraceLog(DEBUG, "Device coordinates: (%f, %f, %f)", deviceCoords.x, deviceCoords.y, deviceCoords.z);
-
+
// Calculate projection matrix (from perspective instead of frustum)
Matrix matProj = MatrixPerspective(camera.fovy, ((double)GetScreenWidth()/(double)GetScreenHeight()), 0.01, 1000.0);
-
+
// Calculate view matrix from camera look at
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
-
+
// Do I need to transpose it? It seems that yes...
// NOTE: matrix order may be incorrect... In OpenGL to get world position from
// camera view it just needs to get inverted, but here we need to transpose it too.
@@ -949,10 +960,10 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
// to a vector, you will get its 3d world position coordinates (camera.position).
// If you don't transpose, final position will be wrong.
MatrixTranspose(&matView);
-
+
//#define USE_RLGL_UNPROJECT
#if defined(USE_RLGL_UNPROJECT) // OPTION 1: Use rlglUnproject()
-
+
Vector3 nearPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 0.0f }, matProj, matView);
Vector3 farPoint = rlglUnproject((Vector3){ deviceCoords.x, deviceCoords.y, 1.0f }, matProj, matView);
@@ -961,56 +972,56 @@ Ray GetMouseRay(Vector2 mousePosition, Camera camera)
// Calculate unproject matrix (multiply projection matrix and view matrix) and invert it
Matrix matProjView = MatrixMultiply(matProj, matView);
MatrixInvert(&matProjView);
-
+
// Calculate far and near points
Quaternion near = { deviceCoords.x, deviceCoords.y, 0.0f, 1.0f };
Quaternion far = { deviceCoords.x, deviceCoords.y, 1.0f, 1.0f };
-
+
// Multiply points by unproject matrix
QuaternionTransform(&near, matProjView);
QuaternionTransform(&far, matProjView);
-
+
// Calculate normalized world points in vectors
Vector3 nearPoint = { near.x/near.w, near.y/near.w, near.z/near.w};
Vector3 farPoint = { far.x/far.w, far.y/far.w, far.z/far.w};
#endif
-
+
// Calculate normalized direction vector
Vector3 direction = VectorSubtract(farPoint, nearPoint);
VectorNormalize(&direction);
-
+
// Apply calculated vectors to ray
ray.position = camera.position;
ray.direction = direction;
-
+
return ray;
}
// Returns the screen space position from a 3d world space position
Vector2 GetWorldToScreen(Vector3 position, Camera camera)
-{
+{
// Calculate projection matrix (from perspective instead of frustum
Matrix matProj = MatrixPerspective(camera.fovy, (double)GetScreenWidth()/(double)GetScreenHeight(), 0.01, 1000.0);
-
+
// Calculate view matrix from camera look at (and transpose it)
Matrix matView = MatrixLookAt(camera.position, camera.target, camera.up);
MatrixTranspose(&matView);
-
+
// Convert world position vector to quaternion
Quaternion worldPos = { position.x, position.y, position.z, 1.0f };
-
+
// Transform world position to view
QuaternionTransform(&worldPos, matView);
-
+
// Transform result to projection (clip space position)
QuaternionTransform(&worldPos, matProj);
-
+
// Calculate normalized device coordinates (inverted y)
- Vector3 ndcPos = { worldPos.x / worldPos.w, -worldPos.y / worldPos.w, worldPos.z / worldPos.z };
-
+ Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.z };
+
// Calculate 2d screen position vector
Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() };
-
+
return screenPosition;
}
@@ -1136,7 +1147,7 @@ bool IsCursorHidden()
bool IsGamepadAvailable(int gamepad)
{
bool result = false;
-
+
#if defined(PLATFORM_RPI)
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
#else
@@ -1150,7 +1161,7 @@ bool IsGamepadAvailable(int gamepad)
float GetGamepadAxisMovement(int gamepad, int axis)
{
float value = 0;
-
+
#if defined(PLATFORM_RPI)
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad])
{
@@ -1159,9 +1170,9 @@ float GetGamepadAxisMovement(int gamepad, int axis)
#else
const float *axes;
int axisCount = 0;
-
+
axes = glfwGetJoystickAxes(gamepad, &axisCount);
-
+
if (axis < axisCount) value = axes[axis];
#endif
@@ -1189,7 +1200,7 @@ bool IsGamepadButtonPressed(int gamepad, int button)
bool IsGamepadButtonDown(int gamepad, int button)
{
bool result = false;
-
+
#if defined(PLATFORM_RPI)
// Get gamepad buttons information
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (gamepadButtons[gamepad][button] == 1)) result = true;
@@ -1197,13 +1208,13 @@ bool IsGamepadButtonDown(int gamepad, int button)
#else
const unsigned char *buttons;
int buttonsCount;
-
+
buttons = glfwGetJoystickButtons(gamepad, &buttonsCount);
if ((buttons != NULL) && (buttons[button] == GLFW_PRESS)) result = true;
else result = false;
#endif
-
+
return result;
}
@@ -1252,7 +1263,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
bool IsMouseButtonPressed(int button)
{
bool pressed = false;
-
+
#if defined(PLATFORM_ANDROID)
if (IsGestureDetected(GESTURE_TAP)) pressed = true;
#else
@@ -1266,13 +1277,13 @@ bool IsMouseButtonPressed(int button)
bool IsMouseButtonDown(int button)
{
bool down = false;
-
+
#if defined(PLATFORM_ANDROID)
if (IsGestureDetected(GESTURE_HOLD)) down = true;
#else
if (GetMouseButtonStatus(button) == 1) down = true;
#endif
-
+
return down;
}
@@ -1280,7 +1291,7 @@ bool IsMouseButtonDown(int button)
bool IsMouseButtonReleased(int button)
{
bool released = false;
-
+
#if !defined(PLATFORM_ANDROID)
if ((currentMouseState[button] != previousMouseState[button]) && (currentMouseState[button] == 0)) released = true;
#endif
@@ -1292,7 +1303,7 @@ bool IsMouseButtonReleased(int button)
bool IsMouseButtonUp(int button)
{
bool up = false;
-
+
#if !defined(PLATFORM_ANDROID)
if (GetMouseButtonStatus(button) == 0) up = true;
#endif
@@ -1377,7 +1388,7 @@ int GetTouchY(void)
Vector2 GetTouchPosition(int index)
{
Vector2 position = { -1.0f, -1.0f };
-
+
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
if (index < MAX_TOUCH_POINTS) position = touchPosition[index];
else TraceLog(WARNING, "Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS);
@@ -1472,23 +1483,28 @@ static void InitGraphicsDevice(int width, int height)
displayHeight = screenHeight;
#endif // defined(PLATFORM_WEB)
- glfwDefaultWindowHints(); // Set default windows hints
+ glfwDefaultWindowHints(); // Set default windows hints
- glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
- //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window
- //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
- //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default)
- //glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window
+ if (configFlags & FLAG_RESIZABLE_WINDOW)
+ {
+ glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
+ }
+ else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
+
+ //glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window
+ //glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
+ //glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default)
+ //glfwWindowHint(GLFW_REFRESH_RATE, 0); // Refresh rate for fullscreen window
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // Default OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
- //glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
+ //glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
// NOTE: When asking for an OpenGL context version, most drivers provide highest supported version
// with forward compatibility to older OpenGL versions.
// For example, if using OpenGL 1.1, driver can provide a 3.3 context fordward compatible.
-
+
if (configFlags & FLAG_MSAA_4X_HINT)
{
- glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
+ glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
TraceLog(INFO, "Trying to enable MSAA x4");
}
@@ -1505,7 +1521,7 @@ static void InitGraphicsDevice(int width, int height)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.3 and above!
// Other values: GLFW_OPENGL_ANY_PROFILE, GLFW_OPENGL_COMPAT_PROFILE
#ifdef __APPLE__
- glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // OSX Requires
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // OSX Requires
#else
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_FALSE); // Fordward Compatibility Hint: Only 3.3 and above!
#endif
@@ -1515,9 +1531,9 @@ static void InitGraphicsDevice(int width, int height)
if (fullscreen)
{
// Obtain recommended displayWidth/displayHeight from a valid videomode for the monitor
- int count;
+ int count;
const GLFWvidmode *modes = glfwGetVideoModes(glfwGetPrimaryMonitor(), &count);
-
+
// Get closest videomode to desired screenWidth/screenHeight
for (int i = 0; i < count; i++)
{
@@ -1531,7 +1547,7 @@ static void InitGraphicsDevice(int width, int height)
}
}
}
-
+
TraceLog(WARNING, "Closest fullscreen videomode: %i x %i", displayWidth, displayHeight);
// NOTE: ISSUE: Closest videomode could not match monitor aspect-ratio, for example,
@@ -1540,12 +1556,12 @@ static void InitGraphicsDevice(int width, int height)
// by the sides to fit all monitor space...
// At this point we need to manage render size vs screen size
- // NOTE: This function uses and modifies global module variables:
+ // NOTE: This function uses and modifies global module variables:
// screenWidth/screenHeight - renderWidth/renderHeight - downscaleView
SetupFramebufferSize(displayWidth, displayHeight);
window = glfwCreateWindow(displayWidth, displayHeight, windowTitle, glfwGetPrimaryMonitor(), NULL);
-
+
// NOTE: Full-screen change, not working properly...
//glfwSetWindowMonitor(window, glfwGetPrimaryMonitor(), 0, 0, screenWidth, screenHeight, GLFW_DONT_CARE);
}
@@ -1553,15 +1569,15 @@ static void InitGraphicsDevice(int width, int height)
{
// No-fullscreen window creation
window = glfwCreateWindow(screenWidth, screenHeight, windowTitle, NULL, NULL);
-
+
#if defined(PLATFORM_DESKTOP)
// 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;
-
+
glfwSetWindowPos(window, windowPosX, windowPosY);
#endif
renderWidth = screenWidth;
@@ -1604,7 +1620,7 @@ static void InitGraphicsDevice(int width, int height)
// NOTE: GLFW loader function is passed as parameter
rlglLoadExtensions(glfwGetProcAddress);
#endif
-
+
// Enables GPU v-sync, so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
// If not set, swap interval uses GPU v-sync configuration
// Framerate can be setup using SetTargetFPS()
@@ -1613,8 +1629,6 @@ static void InitGraphicsDevice(int width, int height)
glfwSwapInterval(1);
TraceLog(INFO, "Trying to enable VSYNC");
}
-
- //glfwGetFramebufferSize(window, &renderWidth, &renderHeight); // Get framebuffer size of current window
#endif // defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
@@ -1637,13 +1651,13 @@ static void InitGraphicsDevice(int width, int height)
EGLint samples = 0;
EGLint sampleBuffer = 0;
- if (configFlags & FLAG_MSAA_4X_HINT)
+ if (configFlags & FLAG_MSAA_4X_HINT)
{
samples = 4;
sampleBuffer = 1;
TraceLog(INFO, "Trying to enable MSAA x4");
}
-
+
const EGLint framebufferAttribs[] =
{
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI?
@@ -1765,17 +1779,28 @@ static void InitGraphicsDevice(int width, int height)
#endif // defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
// Initialize OpenGL context (states and resources)
+ // NOTE: screenWidth and screenHeight not used, just stored as globals
rlglInit(screenWidth, screenHeight);
-
+
+#ifdef __APPLE__
+ // Get framebuffer size of current window
+ // NOTE: Required to handle HighDPI display correctly on OSX because framebuffer
+ // is automatically reasized to adapt to new DPI.
+ // When OS does that, it can be detected using GLFW3 callback: glfwSetFramebufferSizeCallback()
+ int fbWidth, fbHeight;
+ glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
+ rlViewport(renderOffsetX/2, renderOffsetY/2, fbWidth - renderOffsetX, fbHeight - renderOffsetY);
+#else
// Initialize screen viewport (area of the screen that you will actually draw to)
// NOTE: Viewport must be recalculated if screen is resized
rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY);
+#endif
// Initialize internal projection and modelview matrices
// NOTE: Default to orthographic projection mode with top-left corner at (0,0)
rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix
rlLoadIdentity(); // Reset current matrix (PROJECTION)
- rlOrtho(0, renderWidth - renderOffsetX, renderHeight - renderOffsetY, 0, 0.0f, 1.0f);
+ rlOrtho(0, renderWidth - renderOffsetX, renderHeight - renderOffsetY, 0, 0.0f, 1.0f);
rlMatrixMode(RL_MODELVIEW); // Switch back to MODELVIEW matrix
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
@@ -1789,7 +1814,7 @@ static void InitGraphicsDevice(int width, int height)
// Compute framebuffer size relative to screen size and display size
// NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified
static void SetupFramebufferSize(int displayWidth, int displayHeight)
-{
+{
// Calculate renderWidth and renderHeight, we have the display size (input params) and the desired screen size (global var)
if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
{
@@ -1928,7 +1953,7 @@ static void PollInputEvents(void)
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
UpdateGestures();
-
+
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
// Mouse input polling
double mouseX;
@@ -2008,7 +2033,7 @@ static void TakeScreenshot(void)
unsigned char *imgData = rlglReadScreenPixels(renderWidth, renderHeight);
sprintf(buffer, "screenshot%03i.png", shotNum);
-
+
// Save image as PNG
WritePNG(buffer, imgData, renderWidth, renderHeight, 4);
@@ -2043,12 +2068,9 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
// NOTE: Before closing window, while loop must be left!
}
#if defined(PLATFORM_DESKTOP)
- else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
- {
- TakeScreenshot();
- }
+ else if (key == GLFW_KEY_F12 && action == GLFW_PRESS) TakeScreenshot();
#endif
- else
+ else
{
currentKeyState[key] = action;
if (action == GLFW_PRESS) lastKeyPressed = key;
@@ -2059,27 +2081,27 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
{
currentMouseState[button] = action;
-
+
#define ENABLE_MOUSE_GESTURES
#if defined(ENABLE_MOUSE_GESTURES)
// Process mouse events as touches to be able to use mouse-gestures
GestureEvent gestureEvent;
-
+
// Register touch actions
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_DOWN;
else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) gestureEvent.touchAction = TOUCH_UP;
-
+
// NOTE: TOUCH_MOVE event is registered in MouseCursorPosCallback()
-
+
// Assign a pointer ID
gestureEvent.pointerId[0] = 0;
-
+
// Register touch points count
gestureEvent.pointCount = 1;
-
+
// Register touch points position, only one point registered
gestureEvent.position[0] = GetMousePosition();
-
+
// Normalize gestureEvent.position[0] for screenWidth and screenHeight
gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight();
@@ -2098,20 +2120,20 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
GestureEvent gestureEvent;
gestureEvent.touchAction = TOUCH_MOVE;
-
+
// Assign a pointer ID
gestureEvent.pointerId[0] = 0;
// Register touch points count
gestureEvent.pointCount = 1;
-
+
// Register touch points position, only one point registered
gestureEvent.position[0] = (Vector2){ (float)x, (float)y };
-
+
touchPosition[0] = gestureEvent.position[0];
-
+
// Normalize gestureEvent.position[0] for screenWidth and screenHeight
- gestureEvent.position[0].x /= (float)GetScreenWidth();
+ gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight();
// Gesture data is sent to gestures system for processing
@@ -2152,7 +2174,7 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
screenHeight = height;
renderWidth = width;
renderHeight = height;
-
+
// NOTE: Postprocessing texture is not scaled to new size
}
@@ -2171,9 +2193,9 @@ static void WindowIconifyCallback(GLFWwindow* window, int iconified)
static void WindowDropCallback(GLFWwindow *window, int count, const char **paths)
{
ClearDroppedFiles();
-
+
dropFilesPath = (char **)malloc(sizeof(char *)*count);
-
+
for (int i = 0; i < count; i++)
{
dropFilesPath[i] = (char *)malloc(sizeof(char)*256); // Max path length set to 256 char
@@ -2235,7 +2257,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
for (int i = 0; i < assetsCount; i++)
{
// TODO: Unload old asset if required
-
+
// Load texture again to pointed texture
(*textureAsset + i) = LoadTexture(assetPath[i]);
}
@@ -2278,7 +2300,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// NOTE 2: In some cases (too many context loaded), OS could unload context automatically... :(
eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(display, surface);
-
+
contextRebindRequired = true;
TraceLog(INFO, "APP_CMD_TERM_WINDOW");
@@ -2315,7 +2337,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
{
//http://developer.android.com/ndk/reference/index.html
-
+
int type = AInputEvent_getType(event);
if (type == AINPUT_EVENT_TYPE_MOTION)
@@ -2323,7 +2345,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
// Get first touch position
touchPosition[0].x = AMotionEvent_getX(event, 0);
touchPosition[0].y = AMotionEvent_getY(event, 0);
-
+
// Get second touch position
touchPosition[1].x = AMotionEvent_getX(event, 1);
touchPosition[1].y = AMotionEvent_getY(event, 1);
@@ -2332,7 +2354,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
{
int32_t keycode = AKeyEvent_getKeyCode(event);
//int32_t AKeyEvent_getMetaState(event);
-
+
// Save current button and its state
currentButtonState[keycode] = AKeyEvent_getAction(event); // Down = 0, Up = 1
@@ -2344,7 +2366,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
// NOTE: AndroidManifest.xml must have <activity android:configChanges="orientation|keyboardHidden|screenSize" >
// Before that change, activity was calling CMD_TERM_WINDOW and CMD_DESTROY when locking mobile, so that was not a normal behaviour
return 0;
- }
+ }
else if ((keycode == AKEYCODE_BACK) || (keycode == AKEYCODE_MENU))
{
// Eat BACK_BUTTON and AKEYCODE_MENU, just do nothing... and don't let to be handled by OS!
@@ -2356,36 +2378,36 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
return 0;
}
}
-
+
int32_t action = AMotionEvent_getAction(event);
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
-
+
GestureEvent gestureEvent;
-
+
// Register touch actions
if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_DOWN;
else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_UP;
else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_MOVE;
-
+
// Register touch points count
gestureEvent.pointCount = AMotionEvent_getPointerCount(event);
-
+
// Register touch points id
gestureEvent.pointerId[0] = AMotionEvent_getPointerId(event, 0);
gestureEvent.pointerId[1] = AMotionEvent_getPointerId(event, 1);
-
+
// Register touch points position
// NOTE: Only two points registered
gestureEvent.position[0] = (Vector2){ AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) };
gestureEvent.position[1] = (Vector2){ AMotionEvent_getX(event, 1), AMotionEvent_getY(event, 1) };
-
+
// Normalize gestureEvent.position[x] for screenWidth and screenHeight
- gestureEvent.position[0].x /= (float)GetScreenWidth();
+ gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight();
-
- gestureEvent.position[1].x /= (float)GetScreenWidth();
+
+ gestureEvent.position[1].x /= (float)GetScreenWidth();
gestureEvent.position[1].y /= (float)GetScreenHeight();
-
+
// Gesture data is sent to gestures system for processing
ProcessGestureEvent(gestureEvent);
@@ -2396,13 +2418,13 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
#if defined(PLATFORM_WEB)
static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData)
{
- //isFullscreen: int e->isFullscreen
- //fullscreenEnabled: int e->fullscreenEnabled
+ //isFullscreen: int e->isFullscreen
+ //fullscreenEnabled: int e->fullscreenEnabled
//fs element nodeName: (char *) e->nodeName
//fs element id: (char *) e->id
//Current element size: (int) e->elementWidth, (int) e->elementHeight
//Screen size:(int) e->screenWidth, (int) e->screenHeight
-
+
if (e->isFullscreen)
{
TraceLog(INFO, "Canvas scaled to fullscreen. ElementSize: (%ix%i), ScreenSize(%ix%i)", e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight);
@@ -2411,7 +2433,7 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte
{
TraceLog(INFO, "Canvas scaled to windowed. ElementSize: (%ix%i), ScreenSize(%ix%i)", e->elementWidth, e->elementHeight, e->screenWidth, e->screenHeight);
}
-
+
// TODO: Depending on scaling factor (screen vs element), calculate factor to scale mouse/touch input
return 0;
@@ -2431,33 +2453,33 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent
x = touchEvent->touches[i].canvasX;
y = touchEvent->touches[i].canvasY;
}
-
+
printf("%s, numTouches: %d %s%s%s%s\n", emscripten_event_type_to_string(eventType), event->numTouches,
event->ctrlKey ? " CTRL" : "", event->shiftKey ? " SHIFT" : "", event->altKey ? " ALT" : "", event->metaKey ? " META" : "");
- for(int i = 0; i < event->numTouches; ++i)
+ for (int i = 0; i < event->numTouches; ++i)
{
const EmscriptenTouchPoint *t = &event->touches[i];
-
+
printf(" %ld: screen: (%ld,%ld), client: (%ld,%ld), page: (%ld,%ld), isChanged: %d, onTarget: %d, canvas: (%ld, %ld)\n",
t->identifier, t->screenX, t->screenY, t->clientX, t->clientY, t->pageX, t->pageY, t->isChanged, t->onTarget, t->canvasX, t->canvasY);
}
*/
-
+
GestureEvent gestureEvent;
// Register touch actions
if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) gestureEvent.touchAction = TOUCH_DOWN;
else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) gestureEvent.touchAction = TOUCH_UP;
else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) gestureEvent.touchAction = TOUCH_MOVE;
-
+
// Register touch points count
gestureEvent.pointCount = touchEvent->numTouches;
-
+
// Register touch points id
gestureEvent.pointerId[0] = touchEvent->touches[0].identifier;
gestureEvent.pointerId[1] = touchEvent->touches[1].identifier;
-
+
// Register touch points position
// NOTE: Only two points registered
// TODO: Touch data should be scaled accordingly!
@@ -2468,12 +2490,12 @@ static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent
touchPosition[0] = gestureEvent.position[0];
touchPosition[1] = gestureEvent.position[1];
-
+
// Normalize gestureEvent.position[x] for screenWidth and screenHeight
- gestureEvent.position[0].x /= (float)GetScreenWidth();
+ gestureEvent.position[0].x /= (float)GetScreenWidth();
gestureEvent.position[0].y /= (float)GetScreenHeight();
-
- gestureEvent.position[1].x /= (float)GetScreenWidth();
+
+ gestureEvent.position[1].x /= (float)GetScreenWidth();
gestureEvent.position[1].y /= (float)GetScreenHeight();
// Gesture data is sent to gestures system for processing
@@ -2519,7 +2541,7 @@ static void InitKeyboard(void)
else
{
// We reconfigure keyboard mode to get:
- // - scancodes (K_RAW)
+ // - scancodes (K_RAW)
// - keycodes (K_MEDIUMRAW)
// - ASCII chars (K_XLATE)
// - UNICODE chars (K_UNICODE)
@@ -2535,7 +2557,7 @@ static void InitKeyboard(void)
static void ProcessKeyboard(void)
{
#define MAX_KEYBUFFER_SIZE 32 // Max size in bytes to read
-
+
// Keyboard input polling (fill keys[256] array with status)
int bufferByteCount = 0; // Bytes available on the buffer
char keysBuffer[MAX_KEYBUFFER_SIZE]; // Max keys to be read at a time
@@ -2550,7 +2572,7 @@ static void ProcessKeyboard(void)
for (int i = 0; i < bufferByteCount; i++)
{
TraceLog(DEBUG, "Bytes on keysBuffer: %i", bufferByteCount);
-
+
//printf("Key(s) bytes: ");
//for (int i = 0; i < bufferByteCount; i++) printf("0x%02x ", keysBuffer[i]);
//printf("\n");
@@ -2584,7 +2606,7 @@ static void ProcessKeyboard(void)
case 0x34: currentKeyState[301] = 1; break; // raylib KEY_F12
default: break;
}
-
+
if (keysBuffer[i + 2] == 0x5b) i += 4;
else if ((keysBuffer[i + 2] == 0x31) || (keysBuffer[i + 2] == 0x32)) i += 5;
}
@@ -2601,7 +2623,7 @@ static void ProcessKeyboard(void)
i += 3; // Jump to next key
}
-
+
// NOTE: Some keys are not directly keymapped (CTRL, ALT, SHIFT)
}
}
@@ -2611,7 +2633,7 @@ static void ProcessKeyboard(void)
else
{
TraceLog(DEBUG, "Pressed key (ASCII): 0x%02x", keysBuffer[i]);
-
+
// Translate lowercase a-z letters to A-Z
if ((keysBuffer[i] >= 97) && (keysBuffer[i] <= 122))
{
@@ -2620,10 +2642,10 @@ static void ProcessKeyboard(void)
else currentKeyState[(int)keysBuffer[i]] = 1;
}
}
-
+
// Check exit key (same functionality as GLFW3 KeyCallback())
if (currentKeyState[exitKey] == 1) windowShouldClose = true;
-
+
// Check screen capture key
if (currentKeyState[301] == 1) TakeScreenshot(); // raylib key: KEY_F12 (GLFW_KEY_F12)
}
@@ -2633,7 +2655,7 @@ static void RestoreKeyboard(void)
{
// Reset to default keyboard settings
tcsetattr(STDIN_FILENO, TCSANOW, &defaultKeyboardSettings);
-
+
// Reconfigure keyboard to default mode
ioctl(STDIN_FILENO, KDSKBMODE, defaultKeyboardMode);
}
@@ -2663,14 +2685,14 @@ static void InitMouse(void)
static void *MouseThread(void *arg)
{
const unsigned char XSIGN = 1<<4, YSIGN = 1<<5;
-
- typedef struct {
+
+ typedef struct {
char buttons;
- char dx, dy;
+ char dx, dy;
} MouseEvent;
-
+
MouseEvent mouse;
-
+
int mouseRelX = 0;
int mouseRelY = 0;
@@ -2679,7 +2701,7 @@ static void *MouseThread(void *arg)
if (read(mouseStream, &mouse, sizeof(MouseEvent)) == (int)sizeof(MouseEvent))
{
if ((mouse.buttons & 0x08) == 0) break; // This bit should always be set
-
+
// Check Left button pressed
if ((mouse.buttons & 0x01) > 0) currentMouseState[0] = 1;
else currentMouseState[0] = 0;
@@ -2687,27 +2709,27 @@ static void *MouseThread(void *arg)
// Check Right button pressed
if ((mouse.buttons & 0x02) > 0) currentMouseState[1] = 1;
else currentMouseState[1] = 0;
-
+
// Check Middle button pressed
if ((mouse.buttons & 0x04) > 0) currentMouseState[2] = 1;
else currentMouseState[2] = 0;
-
+
mouseRelX = (int)mouse.dx;
mouseRelY = (int)mouse.dy;
-
+
if ((mouse.buttons & XSIGN) > 0) mouseRelX = -1*(255 - mouseRelX);
if ((mouse.buttons & YSIGN) > 0) mouseRelY = -1*(255 - mouseRelY);
-
+
// NOTE: Mouse movement is normalized to not be screen resolution dependant
// We suppose 2*255 (max relative movement) is equivalent to screenWidth (max pixels width)
// Result after normalization is multiplied by MOUSE_SENSITIVITY factor
mousePosition.x += (float)mouseRelX*((float)screenWidth/(2*255))*MOUSE_SENSITIVITY;
mousePosition.y -= (float)mouseRelY*((float)screenHeight/(2*255))*MOUSE_SENSITIVITY;
-
+
if (mousePosition.x < 0) mousePosition.x = 0;
if (mousePosition.y < 0) mousePosition.y = 0;
-
+
if (mousePosition.x > screenWidth) mousePosition.x = screenWidth;
if (mousePosition.y > screenHeight) mousePosition.y = screenHeight;
}
@@ -2721,12 +2743,12 @@ static void *MouseThread(void *arg)
static void InitGamepad(void)
{
char gamepadDev[128] = "";
-
+
for (int i = 0; i < MAX_GAMEPADS; i++)
{
sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i);
-
- if ((gamepadStream[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0)
+
+ if ((gamepadStream[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0)
{
// NOTE: Only show message for first gamepad
if (i == 0) TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available");
@@ -2744,7 +2766,7 @@ static void InitGamepad(void)
else TraceLog(INFO, "Gamepad device initialized successfully");
}
}
- }
+ }
}
// Process Gamepad (/dev/input/js0)
@@ -2763,7 +2785,7 @@ static void *GamepadThread(void *arg)
// Read gamepad event
struct js_event gamepadEvent;
-
+
while (!windowShouldClose)
{
for (int i = 0; i < MAX_GAMEPADS; i++)
@@ -2771,22 +2793,22 @@ static void *GamepadThread(void *arg)
if (read(gamepadStream[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
{
gamepadEvent.type &= ~JS_EVENT_INIT; // Ignore synthetic events
-
+
// Process gamepad events by type
- if (gamepadEvent.type == JS_EVENT_BUTTON)
+ if (gamepadEvent.type == JS_EVENT_BUTTON)
{
TraceLog(DEBUG, "Gamepad button: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
-
- if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS)
+
+ if (gamepadEvent.number < MAX_GAMEPAD_BUTTONS)
{
// 1 - button pressed, 0 - button released
gamepadButtons[i][gamepadEvent.number] = (int)gamepadEvent.value;
}
}
- else if (gamepadEvent.type == JS_EVENT_AXIS)
+ else if (gamepadEvent.type == JS_EVENT_AXIS)
{
TraceLog(DEBUG, "Gamepad axis: %i, value: %i", gamepadEvent.number, gamepadEvent.value);
-
+
if (gamepadEvent.number < MAX_GAMEPAD_AXIS)
{
// NOTE: Scaling of gamepadEvent.value to get values between -1..1
diff --git a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h
index 718c21cb..89293ff8 100644
--- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h
+++ b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h
@@ -1501,9 +1501,9 @@ public:
if (len == 0)
twist->w = T(1); // identity
else
- twist /= len; // normalize
+ *twist /= len; // normalize
- return *this * twist.Inverted();
+ return *this * twist->Inverted();
}
// Normalized linear interpolation of quaternions
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h
index cf7aab62..eaabcf59 100644
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h
+++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h
@@ -271,6 +271,12 @@ typedef char ovrBool; ///< Boolean type
//-----------------------------------------------------------------------------------
// ***** Simple Math Structures
+/// A RGBA color with normalized float components.
+typedef struct OVR_ALIGNAS(4) ovrColorf_
+{
+ float r, g, b, a;
+} ovrColorf;
+
/// A 2D vector with integer components.
typedef struct OVR_ALIGNAS(4) ovrVector2i_
{
@@ -326,7 +332,7 @@ typedef struct OVR_ALIGNAS(4) ovrPosef_
/// A full pose (rigid body) configuration with first and second derivatives.
///
/// Body refers to any object for which ovrPoseStatef is providing data.
-/// It can be the HMD, Touch controller, sensor or something else. The context
+/// It can be the HMD, Touch controller, sensor or something else. The context
/// depends on the usage of the struct.
typedef struct OVR_ALIGNAS(8) ovrPoseStatef_
{
@@ -687,7 +693,7 @@ typedef enum ovrTextureFormat_
///
typedef enum ovrTextureMiscFlags_
{
- ovrTextureMisc_None,
+ ovrTextureMisc_None,
/// DX only: The underlying texture is created with a TYPELESS equivalent of the
/// format specified in the texture desc. The SDK will still access the
@@ -745,28 +751,22 @@ typedef struct ovrMirrorTextureData* ovrMirrorTexture;
//-----------------------------------------------------------------------------------
/// Describes button input types.
-/// Button inputs are combined; that is they will be reported as pressed if they are
+/// Button inputs are combined; that is they will be reported as pressed if they are
/// pressed on either one of the two devices.
/// The ovrButton_Up/Down/Left/Right map to both XBox D-Pad and directional buttons.
/// The ovrButton_Enter and ovrButton_Return map to Start and Back controller buttons, respectively.
typedef enum ovrButton_
-{
+{
ovrButton_A = 0x00000001,
ovrButton_B = 0x00000002,
ovrButton_RThumb = 0x00000004,
ovrButton_RShoulder = 0x00000008,
- // Bit mask of all buttons on the right Touch controller
- ovrButton_RMask = ovrButton_A | ovrButton_B | ovrButton_RThumb | ovrButton_RShoulder,
-
ovrButton_X = 0x00000100,
ovrButton_Y = 0x00000200,
- ovrButton_LThumb = 0x00000400,
+ ovrButton_LThumb = 0x00000400,
ovrButton_LShoulder = 0x00000800,
- // Bit mask of all buttons on the left Touch controller
- ovrButton_LMask = ovrButton_X | ovrButton_Y | ovrButton_LThumb | ovrButton_LShoulder,
-
// Navigation through DPad.
ovrButton_Up = 0x00010000,
ovrButton_Down = 0x00020000,
@@ -776,9 +776,16 @@ typedef enum ovrButton_
ovrButton_Back = 0x00200000, // Back on Xbox controller.
ovrButton_VolUp = 0x00400000, // only supported by Remote.
ovrButton_VolDown = 0x00800000, // only supported by Remote.
- ovrButton_Home = 0x01000000,
+ ovrButton_Home = 0x01000000,
ovrButton_Private = ovrButton_VolUp | ovrButton_VolDown | ovrButton_Home,
+ // Bit mask of all buttons on the right Touch controller
+ ovrButton_RMask = ovrButton_A | ovrButton_B | ovrButton_RThumb | ovrButton_RShoulder,
+
+ // Bit mask of all buttons on the left Touch controller
+ ovrButton_LMask = ovrButton_X | ovrButton_Y | ovrButton_LThumb | ovrButton_LShoulder |
+ ovrButton_Enter,
+
ovrButton_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
} ovrButton;
@@ -806,7 +813,7 @@ typedef enum ovrTouch_
// Bit mask of all the button touches on the left controller
ovrTouch_LButtonMask = ovrTouch_X | ovrTouch_Y | ovrTouch_LThumb | ovrTouch_LThumbRest | ovrTouch_LIndexTrigger,
- // Finger pose state
+ // Finger pose state
// Derived internally based on distance, proximity to sensors and filtering.
ovrTouch_RIndexPointing = 0x00000020,
ovrTouch_RThumbUp = 0x00000040,
@@ -823,6 +830,25 @@ typedef enum ovrTouch_
ovrTouch_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
} ovrTouch;
+/// Describes the Touch Haptics engine.
+/// Currently, those values will NOT change during a session.
+typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTouchHapticsDesc_
+{
+ // Haptics engine frequency/sample-rate, sample time in seconds equals 1.0/sampleRateHz
+ int SampleRateHz;
+ // Size of each Haptics sample, sample value range is [0, 2^(Bytes*8)-1]
+ int SampleSizeInBytes;
+
+ // Queue size that would guarantee Haptics engine would not starve for data
+ // Make sure size doesn't drop below it for best results
+ int QueueMinSizeToAvoidStarvation;
+
+ // Minimum, Maximum and Optimal number of samples that can be sent to Haptics through ovr_SubmitControllerVibration
+ int SubmitMinSamples;
+ int SubmitMaxSamples;
+ int SubmitOptimalSamples;
+} ovrTouchHapticsDesc;
+
/// Specifies which controller is connected; multiple can be connected at once.
typedef enum ovrControllerType_
{
@@ -838,11 +864,45 @@ typedef enum ovrControllerType_
ovrControllerType_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
} ovrControllerType;
+/// Haptics buffer submit mode
+typedef enum ovrHapticsBufferSubmitMode_
+{
+ // Enqueue buffer for later playback
+ ovrHapticsBufferSubmit_Enqueue
+} ovrHapticsBufferSubmitMode;
+
+/// Haptics buffer descriptor, contains amplitude samples used for Touch vibration
+typedef struct ovrHapticsBuffer_
+{
+ const void* Samples;
+ int SamplesCount;
+ ovrHapticsBufferSubmitMode SubmitMode;
+} ovrHapticsBuffer;
+
+/// State of the Haptics playback for Touch vibration
+typedef struct ovrHapticsPlaybackState_
+{
+ // Remaining space available to queue more samples
+ int RemainingQueueSpace;
+
+ // Number of samples currently queued
+ int SamplesQueued;
+} ovrHapticsPlaybackState;
+
+/// Position tracked devices
+typedef enum ovrTrackedDeviceType_
+{
+ ovrTrackedDevice_HMD = 0x0001,
+ ovrTrackedDevice_LTouch = 0x0002,
+ ovrTrackedDevice_RTouch = 0x0004,
+ ovrTrackedDevice_Touch = 0x0006,
+ ovrTrackedDevice_All = 0xFFFF,
+} ovrTrackedDeviceType;
/// Provides names for the left and right hand array indexes.
///
/// \see ovrInputState, ovrTrackingState
-///
+///
typedef enum ovrHandType_
{
ovrHand_Left = 0,
@@ -858,27 +918,43 @@ typedef enum ovrHandType_
/// their inputs are combined.
typedef struct ovrInputState_
{
- // System type when the controller state was last updated.
+ /// System type when the controller state was last updated.
double TimeInSeconds;
- // Values for buttons described by ovrButton.
+ /// Values for buttons described by ovrButton.
unsigned int Buttons;
- // Touch values for buttons and sensors as described by ovrTouch.
+ /// Touch values for buttons and sensors as described by ovrTouch.
unsigned int Touches;
-
- // Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f.
+
+ /// Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f.
+ /// Returns 0 if the value would otherwise be less than 0.1176, for ovrControllerType_XBox
float IndexTrigger[ovrHand_Count];
-
- // Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f.
+
+ /// Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f.
float HandTrigger[ovrHand_Count];
- // Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range -1.0f to 1.0f.
+ /// Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range -1.0f to 1.0f.
+ /// Returns a deadzone (value 0) per each axis if the value on that axis would otherwise have been between -.2746 to +.2746, for ovrControllerType_XBox
ovrVector2f Thumbstick[ovrHand_Count];
- // The type of the controller this state is for.
+ /// The type of the controller this state is for.
ovrControllerType ControllerType;
-
+
+ /// Left and right finger trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f.
+ /// Does not apply a deadzone
+ /// Added in 1.7
+ float IndexTriggerNoDeadzone[ovrHand_Count];
+
+ /// Left and right hand trigger values (ovrHand_Left and ovrHand_Right), in the range 0.0 to 1.0f.
+ /// Does not apply a deadzone
+ /// Added in 1.7
+ float HandTriggerNoDeadzone[ovrHand_Count];
+
+ /// Horizontal and vertical thumbstick axis values (ovrHand_Left and ovrHand_Right), in the range -1.0f to 1.0f
+ /// Does not apply a deadzone
+ /// Added in 1.7
+ ovrVector2f ThumbstickNoDeadzone[ovrHand_Count];
} ovrInputState;
@@ -951,8 +1027,8 @@ typedef struct OVR_ALIGNAS(8) ovrInitParams_
/// Use NULL to specify no log callback.
ovrLogCallback LogCallback;
- /// User-supplied data which is passed as-is to LogCallback. Typically this
- /// is used to store an application-specific pointer which is read in the
+ /// User-supplied data which is passed as-is to LogCallback. Typically this
+ /// is used to store an application-specific pointer which is read in the
/// callback function.
uintptr_t UserData;
@@ -969,6 +1045,7 @@ typedef struct OVR_ALIGNAS(8) ovrInitParams_
extern "C" {
#endif
+#if !defined(OVR_EXPORTING_CAPI)
// -----------------------------------------------------------------------------------
// ***** API Interfaces
@@ -981,7 +1058,7 @@ extern "C" {
/// followed by a call to ovr_Shutdown. ovr_Initialize calls are idempotent.
/// Calling ovr_Initialize twice does not require two matching calls to ovr_Shutdown.
/// If already initialized, the return value is ovr_Success.
-///
+///
/// LibOVRRT shared library search order:
/// -# Current working directory (often the same as the application directory).
/// -# Module directory (usually the same as the application directory,
@@ -1121,21 +1198,21 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity);
///
/// ovr_Initialize must have first been called in order for this to succeed, otherwise ovrHmdDesc::Type
/// will be reported as ovrHmd_None.
-///
+///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create, else NULL in which
/// case this function detects whether an HMD is present and returns its info if so.
///
-/// \return Returns an ovrHmdDesc. If the hmd is NULL and ovrHmdDesc::Type is ovrHmd_None then
+/// \return Returns an ovrHmdDesc. If the hmd is NULL and ovrHmdDesc::Type is ovrHmd_None then
/// no HMD is present.
///
OVR_PUBLIC_FUNCTION(ovrHmdDesc) ovr_GetHmdDesc(ovrSession session);
-/// Returns the number of sensors.
+/// Returns the number of sensors.
///
-/// The number of sensors may change at any time, so this function should be called before use
+/// The number of sensors may change at any time, so this function should be called before use
/// as opposed to once on startup.
-///
+///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
///
/// \return Returns unsigned int count.
@@ -1145,15 +1222,15 @@ OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetTrackerCount(ovrSession session);
/// Returns a given sensor description.
///
-/// It's possible that sensor desc [0] may indicate a unconnnected or non-pose tracked sensor, but
+/// It's possible that sensor desc [0] may indicate a unconnnected or non-pose tracked sensor, but
/// sensor desc [1] may be connected.
///
/// ovr_Initialize must have first been called in order for this to succeed, otherwise the returned
/// trackerDescArray will be zero-initialized. The data returned by this function can change at runtime.
-///
+///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-///
-/// \param[in] trackerDescIndex Specifies a sensor index. The valid indexes are in the range of 0 to
+///
+/// \param[in] trackerDescIndex Specifies a sensor index. The valid indexes are in the range of 0 to
/// the sensor count returned by ovr_GetTrackerCount.
///
/// \return Returns ovrTrackerDesc. An empty ovrTrackerDesc will be returned if trackerDescIndex is out of range.
@@ -1197,6 +1274,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid*
///
OVR_PUBLIC_FUNCTION(void) ovr_Destroy(ovrSession session);
+#endif // !defined(OVR_EXPORTING_CAPI)
/// Specifies status information for the current session.
///
@@ -1208,10 +1286,11 @@ typedef struct ovrSessionStatus_
ovrBool HmdPresent; ///< True if an HMD is present.
ovrBool HmdMounted; ///< True if the HMD is on the user's head.
ovrBool DisplayLost; ///< True if the session is in a display-lost state. See ovr_SubmitFrame.
- ovrBool ShouldQuit; ///< True if the application should initiate shutdown.
+ ovrBool ShouldQuit; ///< True if the application should initiate shutdown.
ovrBool ShouldRecenter; ///< True if UX has requested re-centering. Must call ovr_ClearShouldRecenterFlag or ovr_RecenterTrackingOrigin.
}ovrSessionStatus;
+#if !defined(OVR_EXPORTING_CAPI)
/// Returns status information for the application.
///
@@ -1248,7 +1327,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetSessionStatus(ovrSession session, ovrSessi
///
/// When the tracking origin is changed, all of the calls that either provide
/// or accept ovrPosef will use the new tracking origin provided.
-///
+///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
/// \param[in] origin Specifies an ovrTrackingOrigin to be used for all ovrPosef
///
@@ -1260,7 +1339,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetTrackingOriginType(ovrSession session, ovr
/// Gets the tracking origin state
-///
+///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
///
/// \return Returns the ovrTrackingOrigin that was either set by default, or previous set by the application.
@@ -1274,9 +1353,9 @@ OVR_PUBLIC_FUNCTION(ovrTrackingOrigin) ovr_GetTrackingOriginType(ovrSession sess
/// This resets the (x,y,z) positional components and the yaw orientation component.
/// The Roll and pitch orientation components are always determined by gravity and cannot
/// be redefined. All future tracking will report values relative to this new reference position.
-/// If you are using ovrTrackerPoses then you will need to call ovr_GetTrackerPose after
+/// If you are using ovrTrackerPoses then you will need to call ovr_GetTrackerPose after
/// this, because the sensor position(s) will change as a result of this.
-///
+///
/// The headset cannot be facing vertically upward or downward but rather must be roughly
/// level otherwise this function will fail with ovrError_InvalidHeadsetOrientation.
///
@@ -1298,7 +1377,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_RecenterTrackingOrigin(ovrSession session);
/// Clears the ShouldRecenter status bit in ovrSessionStatus.
///
-/// Clears the ShouldRecenter status bit in ovrSessionStatus, allowing further recenter
+/// Clears the ShouldRecenter status bit in ovrSessionStatus, allowing further recenter
/// requests to be detected. Since this is automatically done by ovr_RecenterTrackingOrigin,
/// this is only needs to be called when application is doing its own re-centering.
OVR_PUBLIC_FUNCTION(void) ovr_ClearShouldRecenterFlag(ovrSession session);
@@ -1358,28 +1437,52 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetInputState(ovrSession session, ovrControll
///
OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetConnectedControllerTypes(ovrSession session);
+/// Gets information about Haptics engine for the specified Touch controller.
+///
+/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
+/// \param[in] controllerType The controller to retrieve the information from.
+///
+/// \return Returns an ovrTouchHapticsDesc.
+///
+OVR_PUBLIC_FUNCTION(ovrTouchHapticsDesc) ovr_GetTouchHapticsDesc(ovrSession session, ovrControllerType controllerType);
-/// Turns on vibration of the given controller.
+/// Sets constant vibration (with specified frequency and amplitude) to a controller.
+/// Note: ovr_SetControllerVibration cannot be used interchangeably with ovr_SubmitControllerVibration.
///
-/// To disable vibration, call ovr_SetControllerVibration with an amplitude of 0.
-/// Vibration automatically stops after a nominal amount of time, so if you want vibration
-/// to be continuous over multiple seconds then you need to call this function periodically.
+/// This method should be called periodically, vibration lasts for a maximum of 2.5 seconds.
+/// It's recommended to call this method once a second, calls will be rejected if called too frequently (over 30hz).
///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] controllerType Specifies the controller to apply the vibration to.
-/// \param[in] frequency Specifies a vibration frequency in the range of 0.0 to 1.0.
-/// Currently the only valid values are 0.0, 0.5, and 1.0 and other values will
-/// be clamped to one of these.
-/// \param[in] amplitude Specifies a vibration amplitude in the range of 0.0 to 1.0.
-///
+/// \param[in] controllerType The controller to set the vibration to.
+/// \param[in] frequency Vibration frequency. Supported values are: 0.0 (disabled), 0.5 and 1.0. Non valid values will be clamped.
+/// \param[in] amplitude Vibration amplitude in the [0.0, 1.0] range.
/// \return Returns ovrSuccess upon success.
///
-/// \see ovrControllerType
-///
OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetControllerVibration(ovrSession session, ovrControllerType controllerType, float frequency, float amplitude);
+/// Submits a Haptics buffer (used for vibration) to Touch (only) controllers.
+/// Note: ovr_SubmitControllerVibration cannot be used interchangeably with ovr_SetControllerVibration.
+///
+/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
+/// \param[in] controllerType Controller where the Haptics buffer will be played.
+/// \param[in] buffer Haptics buffer containing amplitude samples to be played.
+/// \return Returns ovrSuccess upon success.
+/// \see ovrHapticsBuffer
+///
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_SubmitControllerVibration(ovrSession session, ovrControllerType controllerType, const ovrHapticsBuffer* buffer);
+
+/// Gets the Haptics engine playback state of a specific Touch controller.
+///
+/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
+/// \param[in] controllerType Controller where the Haptics buffer wil be played.
+/// \param[in] outState State of the haptics engine.
+/// \return Returns ovrSuccess upon success.
+/// \see ovrHapticsPlaybackState
+///
+OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetControllerVibrationState(ovrSession session, ovrControllerType controllerType, ovrHapticsPlaybackState* outState);
+
-///@}
+#endif // !defined(OVR_EXPORTING_CAPI)
//-------------------------------------------------------------------------------------
// @name Layers
@@ -1603,7 +1706,7 @@ typedef union ovrLayer_Union_
//@}
-
+#if !defined(OVR_EXPORTING_CAPI)
/// @name SDK Distortion Rendering
///
@@ -1626,7 +1729,7 @@ typedef union ovrLayer_Union_
/// \param[in] chain Specifies the ovrTextureSwapChain for which the length should be retrieved.
/// \param[out] out_Length Returns the number of buffers in the specified chain.
///
-/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
+/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
///
/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
///
@@ -1638,7 +1741,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainLength(ovrSession session,
/// \param[in] chain Specifies the ovrTextureSwapChain for which the index should be retrieved.
/// \param[out] out_Index Returns the current (free) index in specified chain.
///
-/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
+/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
///
/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
///
@@ -1650,7 +1753,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainCurrentIndex(ovrSession se
/// \param[in] chain Specifies the ovrTextureSwapChain for which the description should be retrieved.
/// \param[out] out_Desc Returns the description of the specified chain.
///
-/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
+/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
///
/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
///
@@ -1667,7 +1770,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainDesc(ovrSession session, o
/// it will synchronize with the app's graphics context and pick up the submitted index, opening up
/// room in the swap chain for further commits.
///
-/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
+/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error.
/// Failures include but aren't limited to:
/// - ovrError_TextureSwapChainFull: ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain.
///
@@ -1795,7 +1898,7 @@ OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovr_GetRenderDesc(ovrSession session,
/// destroyed (ovr_Destroy) and recreated (ovr_Create), and new resources need to be created
/// (ovr_CreateTextureSwapChainXXX). The application's existing private graphics resources do not
/// need to be recreated unless the new ovr_Create call returns a different GraphicsLuid.
-/// - ovrError_TextureSwapChainInvalid: The ovrTextureSwapChain is in an incomplete or inconsistent state.
+/// - ovrError_TextureSwapChainInvalid: The ovrTextureSwapChain is in an incomplete or inconsistent state.
/// Ensure ovr_CommitTextureSwapChain was called at least once first.
///
/// \see ovr_GetPredictedDisplayTime, ovrViewScaleDesc, ovrLayerHeader
@@ -1805,7 +1908,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_SubmitFrame(ovrSession session, long long fra
ovrLayerHeader const * const * layerPtrList, unsigned int layerCount);
///@}
-
+#endif // !defined(OVR_EXPORTING_CAPI)
//-------------------------------------------------------------------------------------
/// @name Frame Timing
@@ -1813,26 +1916,28 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_SubmitFrame(ovrSession session, long long fra
//@{
+#if !defined(OVR_EXPORTING_CAPI)
+
/// Gets the time of the specified frame midpoint.
///
-/// Predicts the time at which the given frame will be displayed. The predicted time
-/// is the middle of the time period during which the corresponding eye images will
-/// be displayed.
+/// Predicts the time at which the given frame will be displayed. The predicted time
+/// is the middle of the time period during which the corresponding eye images will
+/// be displayed.
///
/// The application should increment frameIndex for each successively targeted frame,
-/// and pass that index to any relevent OVR functions that need to apply to the frame
+/// and pass that index to any relevant OVR functions that need to apply to the frame
/// identified by that index.
///
/// This function is thread-safe and allows for multiple application threads to target
/// their processing to the same displayed frame.
-///
+///
/// In the even that prediction fails due to various reasons (e.g. the display being off
/// or app has yet to present any frames), the return value will be current CPU time.
-///
+///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
/// \param[in] frameIndex Identifies the frame the caller wishes to target.
/// A value of zero returns the next frame index.
-/// \return Returns the absolute frame midpoint time for the given frameIndex.
+/// \return Returns the absolute frame midpoint time for the given frameIndex.
/// \see ovr_GetTimeInSeconds
///
OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long long frameIndex);
@@ -1848,6 +1953,7 @@ OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long
///
OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds();
+#endif // !defined(OVR_EXPORTING_CAPI)
/// Performance HUD enables the HMD user to see information critical to
/// the real-time operation of the VR application such as latency timing,
@@ -1889,7 +1995,7 @@ typedef enum ovrLayerHudMode_
///@}
/// Debug HUD is provided to help developers gauge and debug the fidelity of their app's
-/// stereo rendering characteristics. Using the provided quad and crosshair guides,
+/// stereo rendering characteristics. Using the provided quad and crosshair guides,
/// the developer can verify various aspects such as VR tracking units (e.g. meters),
/// stereo camera-parallax properties (e.g. making sure objects at infinity are rendered
/// with the proper separation), measuring VR geometry sizes and distances and more.
@@ -1915,7 +2021,7 @@ typedef enum ovrDebugHudStereoMode_
} ovrDebugHudStereoMode;
-
+#if !defined(OVR_EXPORTING_CAPI)
// -----------------------------------------------------------------------------------
/// @name Property Access
@@ -2033,7 +2139,7 @@ OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetString(ovrSession session, const char* prope
///@}
-
+#endif // !defined(OVR_EXPORTING_CAPI)
#ifdef __cplusplus
} // extern "C"
@@ -2094,10 +2200,10 @@ OVR_STATIC_ASSERT(sizeof(ovrLogLevel) == 4, "ovrLogLevel size mismatch");
OVR_STATIC_ASSERT(sizeof(ovrInitParams) == 4 + 4 + sizeof(ovrLogCallback) + sizeof(uintptr_t) + 4 + 4,
"ovrInitParams size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrHmdDesc) ==
+OVR_STATIC_ASSERT(sizeof(ovrHmdDesc) ==
+ sizeof(ovrHmdType) // Type
OVR_ON64(+ 4) // pad0
- + 64 // ProductName
+ + 64 // ProductName
+ 64 // Manufacturer
+ 2 // VendorId
+ 2 // ProductId
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h
index 930dfcbe..dc61e19e 100644
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h
+++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h
@@ -17,6 +17,8 @@
#include "OVR_CAPI.h"
#define OVR_AUDIO_MAX_DEVICE_STR_SIZE 128
+#if !defined(OVR_EXPORTING_CAPI)
+
/// Gets the ID of the preferred VR audio output device.
///
/// \param[out] deviceOutId The ID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be WAVE_MAPPER.
@@ -75,6 +77,8 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR deviceInStrBuff
///
OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuid(GUID* deviceInGuid);
+#endif // !defined(OVR_EXPORTING_CAPI)
+
#endif //OVR_OS_MS
#endif // OVR_CAPI_Audio_h
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h
index 982af8f0..374dab84 100644
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h
+++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h
@@ -14,6 +14,8 @@
#if defined (_WIN32)
#include <Unknwn.h>
+#if !defined(OVR_EXPORTING_CAPI)
+
//-----------------------------------------------------------------------------------
// ***** Direct3D Specific
@@ -149,6 +151,7 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session,
IID iid,
void** out_Buffer);
+#endif // !defined(OVR_EXPORTING_CAPI)
#endif // _WIN32
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h
index 81487947..1c073f46 100644
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h
+++ b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h
@@ -9,6 +9,8 @@
#include "OVR_CAPI.h"
+#if !defined(OVR_EXPORTING_CAPI)
+
/// Creates a TextureSwapChain suitable for use with OpenGL.
///
/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
@@ -95,5 +97,6 @@ OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferGL(ovrSession session,
ovrMirrorTexture mirrorTexture,
unsigned int* out_TexId);
+#endif // !defined(OVR_EXPORTING_CAPI)
#endif // OVR_CAPI_GL_h
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h b/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h
index 9fc527c7..a8b810ea 100644
--- a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h
+++ b/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h
@@ -88,6 +88,7 @@ typedef enum ovrErrorType_
ovrError_ClientSkippedDestroy = -1012, ///< The client failed to call ovr_Destroy on an active session before calling ovr_Shutdown. Or the client crashed.
ovrError_ClientSkippedShutdown = -1013, ///< The client failed to call ovr_Shutdown or the client crashed.
ovrError_ServiceDeadlockDetected = -1014, ///< The service watchdog discovered a deadlock.
+ ovrError_InvalidOperation = -1015, ///< Function call is invalid for object's current state
/* Audio error range, reserved for Audio errors. */
ovrError_AudioDeviceNotFound = -2001, ///< Failure to find the specified audio device.
@@ -115,6 +116,9 @@ typedef enum ovrErrorType_
ovrError_HybridGraphicsNotSupported = -3018, ///< The system is using hybrid graphics (Optimus, etc...), which is not support.
ovrError_DisplayManagerInit = -3019, ///< Initialization of the DisplayManager failed.
ovrError_TrackerDriverInit = -3020, ///< Failed to get the interface for an attached tracker
+ ovrError_LibSignCheck = -3021, ///< LibOVRRT signature check failure.
+ ovrError_LibPath = -3022, ///< LibOVRRT path failure.
+ ovrError_LibSymbols = -3023, ///< LibOVRRT symbol resolution failure.
/* Rendering errors */
ovrError_DisplayLost = -6000, ///< In the event of a system-wide graphics reset or cable unplug this is returned to the app.
@@ -130,6 +134,11 @@ typedef enum ovrErrorType_
/* Fatal errors */
ovrError_RuntimeException = -7000, ///< A runtime exception occurred. The application is required to shutdown LibOVR and re-initialize it before this error state will be cleared.
+ /* Calibration errors */
+ ovrError_NoCalibration = -9000, ///< Result of a missing calibration block
+ ovrError_OldVersion = -9001, ///< Result of an old calibration block
+ ovrError_MisformattedBlock = -9002, ///< Result of a bad calibration block due to lengths
+
} ovrErrorType;
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h b/src/external/OculusSDK/LibOVR/Include/OVR_Version.h
index 376fa7d5..8d213df5 100644
--- a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h
+++ b/src/external/OculusSDK/LibOVR/Include/OVR_Version.h
@@ -19,7 +19,7 @@
// Master version numbers
#define OVR_PRODUCT_VERSION 1 // Product version doesn't participate in semantic versioning.
#define OVR_MAJOR_VERSION 1 // If you change these values then you need to also make sure to change LibOVR/Projects/Windows/LibOVR.props in parallel.
-#define OVR_MINOR_VERSION 5 //
+#define OVR_MINOR_VERSION 7 //
#define OVR_PATCH_VERSION 0
#define OVR_BUILD_NUMBER 0
diff --git a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll b/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll
index 8553ce11..7a42d443 100644
--- a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll
+++ b/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll
Binary files differ
diff --git a/src/external/jar_mod.h b/src/external/jar_mod.h
index c39db65a..bee9f6ee 100644
--- a/src/external/jar_mod.h
+++ b/src/external/jar_mod.h
@@ -59,7 +59,7 @@
// - Initialize the jar_mod_context_t buffer. Must be called before doing anything else.
// Return 1 if success. 0 in case of error.
// -------------------------------------------
-// mulong jar_mod_load_file(jar_mod_context_t * modctx, char* filename)
+// mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
//
// - "Load" a MOD from file, context must already be initialized.
// Return size of file in bytes.
@@ -247,7 +247,7 @@ bool jar_mod_init(jar_mod_context_t * modctx);
bool jar_mod_setcfg(jar_mod_context_t * modctx, int samplerate, int bits, int stereo, int stereo_separation, int filter);
void jar_mod_fillbuffer(jar_mod_context_t * modctx, short * outbuffer, unsigned long nbsample, jar_mod_tracker_buffer_state * trkbuf);
void jar_mod_unload(jar_mod_context_t * modctx);
-mulong jar_mod_load_file(jar_mod_context_t * modctx, char* filename);
+mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename);
mulong jar_mod_current_samples(jar_mod_context_t * modctx);
mulong jar_mod_max_samples(jar_mod_context_t * modctx);
void jar_mod_seek_start(jar_mod_context_t * ctx);
@@ -1516,7 +1516,7 @@ void jar_mod_unload( jar_mod_context_t * modctx)
-mulong jar_mod_load_file(jar_mod_context_t * modctx, char* filename)
+mulong jar_mod_load_file(jar_mod_context_t * modctx, const char* filename)
{
mulong fsize = 0;
if(modctx->modfile)
diff --git a/src/external/jar_xm.h b/src/external/jar_xm.h
index f9ddb511..7f0517df 100644
--- a/src/external/jar_xm.h
+++ b/src/external/jar_xm.h
@@ -102,7 +102,7 @@ int jar_xm_create_context_from_file(jar_xm_context_t** ctx, uint32_t rate, const
* @deprecated This function is unsafe!
* @see jar_xm_create_context_safe()
*/
-int jar_xm_create_context(jar_xm_context_t**, const char* moddata, uint32_t rate);
+int jar_xm_create_context(jar_xm_context_t** ctx, const char* moddata, uint32_t rate);
/** Create a XM context.
*
@@ -114,17 +114,17 @@ int jar_xm_create_context(jar_xm_context_t**, const char* moddata, uint32_t rate
* @returns 1 if module data is not sane
* @returns 2 if memory allocation failed
*/
-int jar_xm_create_context_safe(jar_xm_context_t**, const char* moddata, size_t moddata_length, uint32_t rate);
+int jar_xm_create_context_safe(jar_xm_context_t** ctx, const char* moddata, size_t moddata_length, uint32_t rate);
/** Free a XM context created by jar_xm_create_context(). */
-void jar_xm_free_context(jar_xm_context_t*);
+void jar_xm_free_context(jar_xm_context_t* ctx);
/** Play the module and put the sound samples in an output buffer.
*
* @param output buffer of 2*numsamples elements (A left and right value for each sample)
* @param numsamples number of samples to generate
*/
-void jar_xm_generate_samples(jar_xm_context_t*, float* output, size_t numsamples);
+void jar_xm_generate_samples(jar_xm_context_t* ctx, float* output, size_t numsamples);
/** Play the module, resample from 32 bit to 16 bit, and put the sound samples in an output buffer.
*
@@ -173,12 +173,12 @@ void jar_xm_generate_samples_8bit(jar_xm_context_t* ctx, char* output, size_t nu
*
* @param loopcnt maximum number of loops. Use 0 to loop
* indefinitely. */
-void jar_xm_set_max_loop_count(jar_xm_context_t*, uint8_t loopcnt);
+void jar_xm_set_max_loop_count(jar_xm_context_t* ctx, uint8_t loopcnt);
/** Get the loop count of the currently playing module. This value is
* 0 when the module is still playing, 1 when the module has looped
* once, etc. */
-uint8_t jar_xm_get_loop_count(jar_xm_context_t*);
+uint8_t jar_xm_get_loop_count(jar_xm_context_t* ctx);
@@ -188,7 +188,7 @@ uint8_t jar_xm_get_loop_count(jar_xm_context_t*);
*
* @return whether the channel was muted.
*/
-bool jar_xm_mute_channel(jar_xm_context_t*, uint16_t, bool);
+bool jar_xm_mute_channel(jar_xm_context_t* ctx, uint16_t, bool);
/** Mute or unmute an instrument.
*
@@ -197,43 +197,43 @@ bool jar_xm_mute_channel(jar_xm_context_t*, uint16_t, bool);
*
* @return whether the instrument was muted.
*/
-bool jar_xm_mute_instrument(jar_xm_context_t*, uint16_t, bool);
+bool jar_xm_mute_instrument(jar_xm_context_t* ctx, uint16_t, bool);
/** Get the module name as a NUL-terminated string. */
-const char* jar_xm_get_module_name(jar_xm_context_t*);
+const char* jar_xm_get_module_name(jar_xm_context_t* ctx);
/** Get the tracker name as a NUL-terminated string. */
-const char* jar_xm_get_tracker_name(jar_xm_context_t*);
+const char* jar_xm_get_tracker_name(jar_xm_context_t* ctx);
/** Get the number of channels. */
-uint16_t jar_xm_get_number_of_channels(jar_xm_context_t*);
+uint16_t jar_xm_get_number_of_channels(jar_xm_context_t* ctx);
/** Get the module length (in patterns). */
uint16_t jar_xm_get_module_length(jar_xm_context_t*);
/** Get the number of patterns. */
-uint16_t jar_xm_get_number_of_patterns(jar_xm_context_t*);
+uint16_t jar_xm_get_number_of_patterns(jar_xm_context_t* ctx);
/** Get the number of rows of a pattern.
*
* @note Pattern numbers go from 0 to
* jar_xm_get_number_of_patterns(...)-1.
*/
-uint16_t jar_xm_get_number_of_rows(jar_xm_context_t*, uint16_t);
+uint16_t jar_xm_get_number_of_rows(jar_xm_context_t* ctx, uint16_t);
/** Get the number of instruments. */
-uint16_t jar_xm_get_number_of_instruments(jar_xm_context_t*);
+uint16_t jar_xm_get_number_of_instruments(jar_xm_context_t* ctx);
/** Get the number of samples of an instrument.
*
* @note Instrument numbers go from 1 to
* jar_xm_get_number_of_instruments(...).
*/
-uint16_t jar_xm_get_number_of_samples(jar_xm_context_t*, uint16_t);
+uint16_t jar_xm_get_number_of_samples(jar_xm_context_t* ctx, uint16_t);
@@ -242,7 +242,7 @@ uint16_t jar_xm_get_number_of_samples(jar_xm_context_t*, uint16_t);
* @param bpm will receive the current BPM
* @param tempo will receive the current tempo (ticks per line)
*/
-void jar_xm_get_playing_speed(jar_xm_context_t*, uint16_t* bpm, uint16_t* tempo);
+void jar_xm_get_playing_speed(jar_xm_context_t* ctx, uint16_t* bpm, uint16_t* tempo);
/** Get the current position in the module being played.
*
@@ -257,7 +257,7 @@ void jar_xm_get_playing_speed(jar_xm_context_t*, uint16_t* bpm, uint16_t* tempo)
* generated samples (divide by sample rate to get seconds of
* generated audio)
*/
-void jar_xm_get_position(jar_xm_context_t*, uint8_t* pattern_index, uint8_t* pattern, uint8_t* row, uint64_t* samples);
+void jar_xm_get_position(jar_xm_context_t* ctx, uint8_t* pattern_index, uint8_t* pattern, uint8_t* row, uint64_t* samples);
/** Get the latest time (in number of generated samples) when a
* particular instrument was triggered in any channel.
@@ -265,7 +265,7 @@ void jar_xm_get_position(jar_xm_context_t*, uint8_t* pattern_index, uint8_t* pat
* @note Instrument numbers go from 1 to
* jar_xm_get_number_of_instruments(...).
*/
-uint64_t jar_xm_get_latest_trigger_of_instrument(jar_xm_context_t*, uint16_t);
+uint64_t jar_xm_get_latest_trigger_of_instrument(jar_xm_context_t* ctx, uint16_t);
/** Get the latest time (in number of generated samples) when a
* particular sample was triggered in any channel.
@@ -276,21 +276,21 @@ uint64_t jar_xm_get_latest_trigger_of_instrument(jar_xm_context_t*, uint16_t);
* @note Sample numbers go from 0 to
* jar_xm_get_nubmer_of_samples(...,instr)-1.
*/
-uint64_t jar_xm_get_latest_trigger_of_sample(jar_xm_context_t*, uint16_t instr, uint16_t sample);
+uint64_t jar_xm_get_latest_trigger_of_sample(jar_xm_context_t* ctx, uint16_t instr, uint16_t sample);
/** Get the latest time (in number of generated samples) when any
* instrument was triggered in a given channel.
*
* @note Channel numbers go from 1 to jar_xm_get_number_of_channels(...).
*/
-uint64_t jar_xm_get_latest_trigger_of_channel(jar_xm_context_t*, uint16_t);
+uint64_t jar_xm_get_latest_trigger_of_channel(jar_xm_context_t* ctx, uint16_t);
/** Get the number of remaining samples. Divide by 2 to get the number of individual LR data samples.
*
* @note This is the remaining number of samples before the loop starts module again, or halts if on last pass.
* @note This function is very slow and should only be run once, if at all.
*/
-uint64_t jar_xm_get_remaining_samples(jar_xm_context_t*);
+uint64_t jar_xm_get_remaining_samples(jar_xm_context_t* ctx);
#ifdef __cplusplus
}
@@ -308,7 +308,7 @@ uint64_t jar_xm_get_remaining_samples(jar_xm_context_t*);
#include <math.h>
#include <string.h>
-#if JAR_XM_DEBUG
+#ifdef JAR_XM_DEBUG
#include <stdio.h>
#define DEBUG(fmt, ...) do { \
fprintf(stderr, "%s(): " fmt "\n", __func__, __VA_ARGS__); \
@@ -638,7 +638,7 @@ int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, siz
/* Initialize most of the fields to 0, 0.f, NULL or false depending on type */
memset(mempool, 0, bytes_needed);
- ctx = (*ctxp = (jar_xm_context_t*)mempool);
+ ctx = (*ctxp = (jar_xm_context_t *)mempool);
ctx->allocated_memory = mempool; /* Keep original pointer for free() */
mempool += sizeof(jar_xm_context_t);
@@ -685,20 +685,18 @@ int jar_xm_create_context_safe(jar_xm_context_t** ctxp, const char* moddata, siz
return 0;
}
-void jar_xm_free_context(jar_xm_context_t* context) {
- free(context->allocated_memory);
+void jar_xm_free_context(jar_xm_context_t* ctx) {
+ free(ctx->allocated_memory);
}
-void jar_xm_set_max_loop_count(jar_xm_context_t* context, uint8_t loopcnt) {
- context->max_loop_count = loopcnt;
+void jar_xm_set_max_loop_count(jar_xm_context_t* ctx, uint8_t loopcnt) {
+ ctx->max_loop_count = loopcnt;
}
-uint8_t jar_xm_get_loop_count(jar_xm_context_t* context) {
- return context->loop_count;
+uint8_t jar_xm_get_loop_count(jar_xm_context_t* ctx) {
+ return ctx->loop_count;
}
-
-
bool jar_xm_mute_channel(jar_xm_context_t* ctx, uint16_t channel, bool mute) {
bool old = ctx->channels[channel - 1].muted;
ctx->channels[channel - 1].muted = mute;
@@ -1435,7 +1433,7 @@ static void jar_xm_volume_slide(jar_xm_channel_context_t* ch, uint8_t rawval) {
}
}
-static float jar_xm_envelope_lerp(jar_xm_envelope_point_t* restrict a, jar_xm_envelope_point_t* restrict b, uint16_t pos) {
+static float jar_xm_envelope_lerp(jar_xm_envelope_point_t* a, jar_xm_envelope_point_t* b, uint16_t pos) {
/* Linear interpolation between two envelope points */
if(pos <= a->frame) return a->value;
else if(pos >= b->frame) return b->value;
diff --git a/src/external/lua/include/lauxlib.h b/src/external/lua/include/lauxlib.h
new file mode 100644
index 00000000..ddb7c228
--- /dev/null
+++ b/src/external/lua/include/lauxlib.h
@@ -0,0 +1,256 @@
+/*
+** $Id: lauxlib.h,v 1.129 2015/11/23 11:29:43 roberto Exp $
+** Auxiliary functions for building Lua libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lauxlib_h
+#define lauxlib_h
+
+
+#include <stddef.h>
+#include <stdio.h>
+
+#include "lua.h"
+
+
+
+/* extra error code for 'luaL_load' */
+#define LUA_ERRFILE (LUA_ERRERR+1)
+
+
+typedef struct luaL_Reg {
+ const char *name;
+ lua_CFunction func;
+} luaL_Reg;
+
+
+#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number))
+
+LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz);
+#define luaL_checkversion(L) \
+ luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
+
+LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
+LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
+LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
+LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
+LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
+ size_t *l);
+LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
+ const char *def, size_t *l);
+LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
+LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
+
+LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
+LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
+ lua_Integer def);
+
+LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
+LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
+
+LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
+LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
+LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
+LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
+
+LUALIB_API void (luaL_where) (lua_State *L, int lvl);
+LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
+
+LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
+ const char *const lst[]);
+
+LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
+LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
+
+/* predefined references */
+#define LUA_NOREF (-2)
+#define LUA_REFNIL (-1)
+
+LUALIB_API int (luaL_ref) (lua_State *L, int t);
+LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
+
+LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
+ const char *mode);
+
+#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
+
+LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
+ const char *name, const char *mode);
+LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
+
+LUALIB_API lua_State *(luaL_newstate) (void);
+
+LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
+
+LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
+ const char *r);
+
+LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
+
+LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
+
+LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
+ const char *msg, int level);
+
+LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
+ lua_CFunction openf, int glb);
+
+/*
+** ===============================================================
+** some useful macros
+** ===============================================================
+*/
+
+
+#define luaL_newlibtable(L,l) \
+ lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
+
+#define luaL_newlib(L,l) \
+ (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+
+#define luaL_argcheck(L, cond,arg,extramsg) \
+ ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
+#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
+#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
+
+#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
+
+#define luaL_dofile(L, fn) \
+ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_dostring(L, s) \
+ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
+
+#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
+
+#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
+
+#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
+
+
+/*
+** {======================================================
+** Generic Buffer manipulation
+** =======================================================
+*/
+
+typedef struct luaL_Buffer {
+ char *b; /* buffer address */
+ size_t size; /* buffer size */
+ size_t n; /* number of characters in buffer */
+ lua_State *L;
+ char initb[LUAL_BUFFERSIZE]; /* initial buffer */
+} luaL_Buffer;
+
+
+#define luaL_addchar(B,c) \
+ ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
+ ((B)->b[(B)->n++] = (c)))
+
+#define luaL_addsize(B,s) ((B)->n += (s))
+
+LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
+LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
+LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
+LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
+LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
+LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
+
+#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
+
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** File handles for IO library
+** =======================================================
+*/
+
+/*
+** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
+** initial structure 'luaL_Stream' (it may contain other fields
+** after that initial structure).
+*/
+
+#define LUA_FILEHANDLE "FILE*"
+
+
+typedef struct luaL_Stream {
+ FILE *f; /* stream (NULL for incompletely created streams) */
+ lua_CFunction closef; /* to close stream (NULL for closed streams) */
+} luaL_Stream;
+
+/* }====================================================== */
+
+
+
+/* compatibility with old module system */
+#if defined(LUA_COMPAT_MODULE)
+
+LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
+ int sizehint);
+LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
+ const luaL_Reg *l, int nup);
+
+#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
+
+#endif
+
+
+/*
+** {==================================================================
+** "Abstraction Layer" for basic report of messages and errors
+** ===================================================================
+*/
+
+/* print a string */
+#if !defined(lua_writestring)
+#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
+#endif
+
+/* print a newline and flush the output */
+#if !defined(lua_writeline)
+#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
+#endif
+
+/* print an error message */
+#if !defined(lua_writestringerror)
+#define lua_writestringerror(s,p) \
+ (fprintf(stderr, (s), (p)), fflush(stderr))
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {============================================================
+** Compatibility with deprecated conversions
+** =============================================================
+*/
+#if defined(LUA_COMPAT_APIINTCASTS)
+
+#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
+#define luaL_optunsigned(L,a,d) \
+ ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d)))
+
+#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
+#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
+
+#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
+#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
+
+#endif
+/* }============================================================ */
+
+
+
+#endif
+
+
diff --git a/src/external/lua/include/lua.h b/src/external/lua/include/lua.h
new file mode 100644
index 00000000..f78899fc
--- /dev/null
+++ b/src/external/lua/include/lua.h
@@ -0,0 +1,486 @@
+/*
+** $Id: lua.h,v 1.331 2016/05/30 15:53:28 roberto Exp $
+** Lua - A Scripting Language
+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
+** See Copyright Notice at the end of this file
+*/
+
+
+#ifndef lua_h
+#define lua_h
+
+#include <stdarg.h>
+#include <stddef.h>
+
+
+#include "luaconf.h"
+
+
+#define LUA_VERSION_MAJOR "5"
+#define LUA_VERSION_MINOR "3"
+#define LUA_VERSION_NUM 503
+#define LUA_VERSION_RELEASE "3"
+
+#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
+#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2016 Lua.org, PUC-Rio"
+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
+
+
+/* mark for precompiled code ('<esc>Lua') */
+#define LUA_SIGNATURE "\x1bLua"
+
+/* option for multiple returns in 'lua_pcall' and 'lua_call' */
+#define LUA_MULTRET (-1)
+
+
+/*
+** Pseudo-indices
+** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
+** space after that to help overflow detection)
+*/
+#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
+#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
+
+
+/* thread status */
+#define LUA_OK 0
+#define LUA_YIELD 1
+#define LUA_ERRRUN 2
+#define LUA_ERRSYNTAX 3
+#define LUA_ERRMEM 4
+#define LUA_ERRGCMM 5
+#define LUA_ERRERR 6
+
+
+typedef struct lua_State lua_State;
+
+
+/*
+** basic types
+*/
+#define LUA_TNONE (-1)
+
+#define LUA_TNIL 0
+#define LUA_TBOOLEAN 1
+#define LUA_TLIGHTUSERDATA 2
+#define LUA_TNUMBER 3
+#define LUA_TSTRING 4
+#define LUA_TTABLE 5
+#define LUA_TFUNCTION 6
+#define LUA_TUSERDATA 7
+#define LUA_TTHREAD 8
+
+#define LUA_NUMTAGS 9
+
+
+
+/* minimum Lua stack available to a C function */
+#define LUA_MINSTACK 20
+
+
+/* predefined values in the registry */
+#define LUA_RIDX_MAINTHREAD 1
+#define LUA_RIDX_GLOBALS 2
+#define LUA_RIDX_LAST LUA_RIDX_GLOBALS
+
+
+/* type of numbers in Lua */
+typedef LUA_NUMBER lua_Number;
+
+
+/* type for integer functions */
+typedef LUA_INTEGER lua_Integer;
+
+/* unsigned integer type */
+typedef LUA_UNSIGNED lua_Unsigned;
+
+/* type for continuation-function contexts */
+typedef LUA_KCONTEXT lua_KContext;
+
+
+/*
+** Type for C functions registered with Lua
+*/
+typedef int (*lua_CFunction) (lua_State *L);
+
+/*
+** Type for continuation functions
+*/
+typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
+
+
+/*
+** Type for functions that read/write blocks when loading/dumping Lua chunks
+*/
+typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
+
+typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
+
+
+/*
+** Type for memory-allocation functions
+*/
+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
+
+
+
+/*
+** generic extra include file
+*/
+#if defined(LUA_USER_H)
+#include LUA_USER_H
+#endif
+
+
+/*
+** RCS ident string
+*/
+extern const char lua_ident[];
+
+
+/*
+** state manipulation
+*/
+LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
+LUA_API void (lua_close) (lua_State *L);
+LUA_API lua_State *(lua_newthread) (lua_State *L);
+
+LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
+
+
+LUA_API const lua_Number *(lua_version) (lua_State *L);
+
+
+/*
+** basic stack manipulation
+*/
+LUA_API int (lua_absindex) (lua_State *L, int idx);
+LUA_API int (lua_gettop) (lua_State *L);
+LUA_API void (lua_settop) (lua_State *L, int idx);
+LUA_API void (lua_pushvalue) (lua_State *L, int idx);
+LUA_API void (lua_rotate) (lua_State *L, int idx, int n);
+LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx);
+LUA_API int (lua_checkstack) (lua_State *L, int n);
+
+LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
+
+
+/*
+** access functions (stack -> C)
+*/
+
+LUA_API int (lua_isnumber) (lua_State *L, int idx);
+LUA_API int (lua_isstring) (lua_State *L, int idx);
+LUA_API int (lua_iscfunction) (lua_State *L, int idx);
+LUA_API int (lua_isinteger) (lua_State *L, int idx);
+LUA_API int (lua_isuserdata) (lua_State *L, int idx);
+LUA_API int (lua_type) (lua_State *L, int idx);
+LUA_API const char *(lua_typename) (lua_State *L, int tp);
+
+LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
+LUA_API int (lua_toboolean) (lua_State *L, int idx);
+LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
+LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
+LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
+LUA_API void *(lua_touserdata) (lua_State *L, int idx);
+LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
+LUA_API const void *(lua_topointer) (lua_State *L, int idx);
+
+
+/*
+** Comparison and arithmetic functions
+*/
+
+#define LUA_OPADD 0 /* ORDER TM, ORDER OP */
+#define LUA_OPSUB 1
+#define LUA_OPMUL 2
+#define LUA_OPMOD 3
+#define LUA_OPPOW 4
+#define LUA_OPDIV 5
+#define LUA_OPIDIV 6
+#define LUA_OPBAND 7
+#define LUA_OPBOR 8
+#define LUA_OPBXOR 9
+#define LUA_OPSHL 10
+#define LUA_OPSHR 11
+#define LUA_OPUNM 12
+#define LUA_OPBNOT 13
+
+LUA_API void (lua_arith) (lua_State *L, int op);
+
+#define LUA_OPEQ 0
+#define LUA_OPLT 1
+#define LUA_OPLE 2
+
+LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
+
+
+/*
+** push functions (C -> stack)
+*/
+LUA_API void (lua_pushnil) (lua_State *L);
+LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
+LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len);
+LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
+LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
+ va_list argp);
+LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
+LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
+LUA_API void (lua_pushboolean) (lua_State *L, int b);
+LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
+LUA_API int (lua_pushthread) (lua_State *L);
+
+
+/*
+** get functions (Lua -> stack)
+*/
+LUA_API int (lua_getglobal) (lua_State *L, const char *name);
+LUA_API int (lua_gettable) (lua_State *L, int idx);
+LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
+LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n);
+LUA_API int (lua_rawget) (lua_State *L, int idx);
+LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
+LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
+
+LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
+LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
+LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
+LUA_API int (lua_getuservalue) (lua_State *L, int idx);
+
+
+/*
+** set functions (stack -> Lua)
+*/
+LUA_API void (lua_setglobal) (lua_State *L, const char *name);
+LUA_API void (lua_settable) (lua_State *L, int idx);
+LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
+LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n);
+LUA_API void (lua_rawset) (lua_State *L, int idx);
+LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n);
+LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
+LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
+LUA_API void (lua_setuservalue) (lua_State *L, int idx);
+
+
+/*
+** 'load' and 'call' functions (load and run Lua code)
+*/
+LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults,
+ lua_KContext ctx, lua_KFunction k);
+#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
+
+LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
+ lua_KContext ctx, lua_KFunction k);
+#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
+
+LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
+ const char *chunkname, const char *mode);
+
+LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
+
+
+/*
+** coroutine functions
+*/
+LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx,
+ lua_KFunction k);
+LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
+LUA_API int (lua_status) (lua_State *L);
+LUA_API int (lua_isyieldable) (lua_State *L);
+
+#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
+
+
+/*
+** garbage-collection function and options
+*/
+
+#define LUA_GCSTOP 0
+#define LUA_GCRESTART 1
+#define LUA_GCCOLLECT 2
+#define LUA_GCCOUNT 3
+#define LUA_GCCOUNTB 4
+#define LUA_GCSTEP 5
+#define LUA_GCSETPAUSE 6
+#define LUA_GCSETSTEPMUL 7
+#define LUA_GCISRUNNING 9
+
+LUA_API int (lua_gc) (lua_State *L, int what, int data);
+
+
+/*
+** miscellaneous functions
+*/
+
+LUA_API int (lua_error) (lua_State *L);
+
+LUA_API int (lua_next) (lua_State *L, int idx);
+
+LUA_API void (lua_concat) (lua_State *L, int n);
+LUA_API void (lua_len) (lua_State *L, int idx);
+
+LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s);
+
+LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
+LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
+
+
+
+/*
+** {==============================================================
+** some useful macros
+** ===============================================================
+*/
+
+#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
+
+#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL)
+#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL)
+
+#define lua_pop(L,n) lua_settop(L, -(n)-1)
+
+#define lua_newtable(L) lua_createtable(L, 0, 0)
+
+#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
+
+#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
+
+#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
+#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
+#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
+#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
+#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
+#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
+#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
+#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
+
+#define lua_pushliteral(L, s) lua_pushstring(L, "" s)
+
+#define lua_pushglobaltable(L) \
+ ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS))
+
+#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
+
+
+#define lua_insert(L,idx) lua_rotate(L, (idx), 1)
+
+#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
+
+#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
+
+/* }============================================================== */
+
+
+/*
+** {==============================================================
+** compatibility macros for unsigned conversions
+** ===============================================================
+*/
+#if defined(LUA_COMPAT_APIINTCASTS)
+
+#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
+#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is))
+#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL)
+
+#endif
+/* }============================================================== */
+
+/*
+** {======================================================================
+** Debug API
+** =======================================================================
+*/
+
+
+/*
+** Event codes
+*/
+#define LUA_HOOKCALL 0
+#define LUA_HOOKRET 1
+#define LUA_HOOKLINE 2
+#define LUA_HOOKCOUNT 3
+#define LUA_HOOKTAILCALL 4
+
+
+/*
+** Event masks
+*/
+#define LUA_MASKCALL (1 << LUA_HOOKCALL)
+#define LUA_MASKRET (1 << LUA_HOOKRET)
+#define LUA_MASKLINE (1 << LUA_HOOKLINE)
+#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
+
+typedef struct lua_Debug lua_Debug; /* activation record */
+
+
+/* Functions to be called by the debugger in specific events */
+typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
+
+
+LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
+LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
+LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
+LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
+
+LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
+LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
+ int fidx2, int n2);
+
+LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
+LUA_API lua_Hook (lua_gethook) (lua_State *L);
+LUA_API int (lua_gethookmask) (lua_State *L);
+LUA_API int (lua_gethookcount) (lua_State *L);
+
+
+struct lua_Debug {
+ int event;
+ const char *name; /* (n) */
+ const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */
+ const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */
+ const char *source; /* (S) */
+ int currentline; /* (l) */
+ int linedefined; /* (S) */
+ int lastlinedefined; /* (S) */
+ unsigned char nups; /* (u) number of upvalues */
+ unsigned char nparams;/* (u) number of parameters */
+ char isvararg; /* (u) */
+ char istailcall; /* (t) */
+ char short_src[LUA_IDSIZE]; /* (S) */
+ /* private part */
+ struct CallInfo *i_ci; /* active function */
+};
+
+/* }====================================================================== */
+
+
+/******************************************************************************
+* Copyright (C) 1994-2016 Lua.org, PUC-Rio.
+*
+* Permission is hereby granted, free of charge, to any person obtaining
+* a copy of this software and associated documentation files (the
+* "Software"), to deal in the Software without restriction, including
+* without limitation the rights to use, copy, modify, merge, publish,
+* distribute, sublicense, and/or sell copies of the Software, and to
+* permit persons to whom the Software is 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 Software.
+*
+* 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 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
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+
+#endif
diff --git a/src/external/lua/include/lua.hpp b/src/external/lua/include/lua.hpp
new file mode 100644
index 00000000..ec417f59
--- /dev/null
+++ b/src/external/lua/include/lua.hpp
@@ -0,0 +1,9 @@
+// lua.hpp
+// Lua header files for C++
+// <<extern "C">> not supplied automatically because Lua also compiles as C++
+
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
diff --git a/src/external/lua/include/luaconf.h b/src/external/lua/include/luaconf.h
new file mode 100644
index 00000000..867e9cb1
--- /dev/null
+++ b/src/external/lua/include/luaconf.h
@@ -0,0 +1,769 @@
+/*
+** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp $
+** Configuration file for Lua
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef luaconf_h
+#define luaconf_h
+
+#include <limits.h>
+#include <stddef.h>
+
+
+/*
+** ===================================================================
+** Search for "@@" to find all configurable definitions.
+** ===================================================================
+*/
+
+
+/*
+** {====================================================================
+** System Configuration: macros to adapt (if needed) Lua to some
+** particular platform, for instance compiling it with 32-bit numbers or
+** restricting it to C89.
+** =====================================================================
+*/
+
+/*
+@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. You
+** can also define LUA_32BITS in the make file, but changing here you
+** ensure that all software connected to Lua will be compiled with the
+** same configuration.
+*/
+/* #define LUA_32BITS */
+
+
+/*
+@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
+** Define it if you want Lua to avoid the use of a few C99 features
+** or Windows-specific features on Windows.
+*/
+/* #define LUA_USE_C89 */
+
+
+/*
+** By default, Lua on Windows use (some) specific Windows features
+*/
+#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_USE_WINDOWS /* enable goodies for regular Windows */
+#endif
+
+
+#if defined(LUA_USE_WINDOWS)
+#define LUA_DL_DLL /* enable support for DLL */
+#define LUA_USE_C89 /* broadly, Windows is C89 */
+#endif
+
+
+#if defined(LUA_USE_LINUX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
+#define LUA_USE_READLINE /* needs some extra libraries */
+#endif
+
+
+#if defined(LUA_USE_MACOSX)
+#define LUA_USE_POSIX
+#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
+#define LUA_USE_READLINE /* needs an extra library: -lreadline */
+#endif
+
+
+/*
+@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
+** C89 ('long' and 'double'); Windows always has '__int64', so it does
+** not need to use this case.
+*/
+#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
+#define LUA_C89_NUMBERS
+#endif
+
+
+
+/*
+@@ LUAI_BITSINT defines the (minimum) number of bits in an 'int'.
+*/
+/* avoid undefined shifts */
+#if ((INT_MAX >> 15) >> 15) >= 1
+#define LUAI_BITSINT 32
+#else
+/* 'int' always must have at least 16 bits */
+#define LUAI_BITSINT 16
+#endif
+
+
+/*
+@@ LUA_INT_TYPE defines the type for Lua integers.
+@@ LUA_FLOAT_TYPE defines the type for Lua floats.
+** Lua should work fine with any mix of these options (if supported
+** by your C compiler). The usual configurations are 64-bit integers
+** and 'double' (the default), 32-bit integers and 'float' (for
+** restricted platforms), and 'long'/'double' (for C compilers not
+** compliant with C99, which may not have support for 'long long').
+*/
+
+/* predefined options for LUA_INT_TYPE */
+#define LUA_INT_INT 1
+#define LUA_INT_LONG 2
+#define LUA_INT_LONGLONG 3
+
+/* predefined options for LUA_FLOAT_TYPE */
+#define LUA_FLOAT_FLOAT 1
+#define LUA_FLOAT_DOUBLE 2
+#define LUA_FLOAT_LONGDOUBLE 3
+
+#if defined(LUA_32BITS) /* { */
+/*
+** 32-bit integers and 'float'
+*/
+#if LUAI_BITSINT >= 32 /* use 'int' if big enough */
+#define LUA_INT_TYPE LUA_INT_INT
+#else /* otherwise use 'long' */
+#define LUA_INT_TYPE LUA_INT_LONG
+#endif
+#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
+
+#elif defined(LUA_C89_NUMBERS) /* }{ */
+/*
+** largest types available for C89 ('long' and 'double')
+*/
+#define LUA_INT_TYPE LUA_INT_LONG
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
+
+#endif /* } */
+
+
+/*
+** default configuration for 64-bit Lua ('long long' and 'double')
+*/
+#if !defined(LUA_INT_TYPE)
+#define LUA_INT_TYPE LUA_INT_LONGLONG
+#endif
+
+#if !defined(LUA_FLOAT_TYPE)
+#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
+#endif
+
+/* }================================================================== */
+
+
+
+
+/*
+** {==================================================================
+** Configuration for Paths.
+** ===================================================================
+*/
+
+/*
+@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
+** Lua libraries.
+@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
+** C libraries.
+** CHANGE them if your machine has a non-conventional directory
+** hierarchy or if you want to install your libraries in
+** non-conventional directories.
+*/
+#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#if defined(_WIN32) /* { */
+/*
+** In Windows, any exclamation mark ('!') in the path is replaced by the
+** path of the directory of the executable file of the current process.
+*/
+#define LUA_LDIR "!\\lua\\"
+#define LUA_CDIR "!\\"
+#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\"
+#define LUA_PATH_DEFAULT \
+ LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \
+ LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \
+ ".\\?.lua;" ".\\?\\init.lua"
+#define LUA_CPATH_DEFAULT \
+ LUA_CDIR"?.dll;" \
+ LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \
+ LUA_CDIR"loadall.dll;" ".\\?.dll;" \
+ LUA_CDIR"?53.dll;" ".\\?53.dll"
+
+#else /* }{ */
+
+#define LUA_ROOT "/usr/local/"
+#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
+#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
+#define LUA_PATH_DEFAULT \
+ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \
+ "./?.lua;" "./?/init.lua"
+#define LUA_CPATH_DEFAULT \
+ LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so;" \
+ LUA_CDIR"lib?53.so;" "./lib?53.so"
+#endif /* } */
+
+
+/*
+@@ LUA_DIRSEP is the directory separator (for submodules).
+** CHANGE it if your machine does not use "/" as the directory separator
+** and is not Windows. (On Windows Lua automatically uses "\".)
+*/
+#if defined(_WIN32)
+#define LUA_DIRSEP "\\"
+#else
+#define LUA_DIRSEP "/"
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Marks for exported symbols in the C code
+** ===================================================================
+*/
+
+/*
+@@ LUA_API is a mark for all core API functions.
+@@ LUALIB_API is a mark for all auxiliary library functions.
+@@ LUAMOD_API is a mark for all standard library opening functions.
+** CHANGE them if you need to define those functions in some special way.
+** For instance, if you want to create one Windows DLL with the core and
+** the libraries, you may want to use the following definition (define
+** LUA_BUILD_AS_DLL to get it).
+*/
+#if defined(LUA_BUILD_AS_DLL) /* { */
+
+#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
+#define LUA_API __declspec(dllexport)
+#else /* }{ */
+#define LUA_API __declspec(dllimport)
+#endif /* } */
+
+#else /* }{ */
+
+#define LUA_API extern
+
+#endif /* } */
+
+
+/* more often than not the libs go together with the core */
+#define LUALIB_API LUA_API
+#define LUAMOD_API LUALIB_API
+
+
+/*
+@@ LUAI_FUNC is a mark for all extern functions that are not to be
+** exported to outside modules.
+@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
+** that are not to be exported to outside modules (LUAI_DDEF for
+** definitions and LUAI_DDEC for declarations).
+** CHANGE them if you need to mark them in some special way. Elf/gcc
+** (versions 3.2 and later) mark them as "hidden" to optimize access
+** when Lua is compiled as a shared library. Not all elf targets support
+** this attribute. Unfortunately, gcc does not offer a way to check
+** whether the target offers that support, and those without support
+** give a warning about it. To avoid these warnings, change to the
+** default definition.
+*/
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+ defined(__ELF__) /* { */
+#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
+#else /* }{ */
+#define LUAI_FUNC extern
+#endif /* } */
+
+#define LUAI_DDEC LUAI_FUNC
+#define LUAI_DDEF /* empty */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Compatibility with previous versions
+** ===================================================================
+*/
+
+/*
+@@ LUA_COMPAT_5_2 controls other macros for compatibility with Lua 5.2.
+@@ LUA_COMPAT_5_1 controls other macros for compatibility with Lua 5.1.
+** You can define it to get all options, or change specific options
+** to fit your specific needs.
+*/
+#if defined(LUA_COMPAT_5_2) /* { */
+
+/*
+@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
+** functions in the mathematical library.
+*/
+#define LUA_COMPAT_MATHLIB
+
+/*
+@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'.
+*/
+#define LUA_COMPAT_BITLIB
+
+/*
+@@ LUA_COMPAT_IPAIRS controls the effectiveness of the __ipairs metamethod.
+*/
+#define LUA_COMPAT_IPAIRS
+
+/*
+@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
+** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
+** luaL_checkint, luaL_checklong, etc.)
+*/
+#define LUA_COMPAT_APIINTCASTS
+
+#endif /* } */
+
+
+#if defined(LUA_COMPAT_5_1) /* { */
+
+/* Incompatibilities from 5.2 -> 5.3 */
+#define LUA_COMPAT_MATHLIB
+#define LUA_COMPAT_APIINTCASTS
+
+/*
+@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
+** You can replace it with 'table.unpack'.
+*/
+#define LUA_COMPAT_UNPACK
+
+/*
+@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
+** You can replace it with 'package.searchers'.
+*/
+#define LUA_COMPAT_LOADERS
+
+/*
+@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
+** You can call your C function directly (with light C functions).
+*/
+#define lua_cpcall(L,f,u) \
+ (lua_pushcfunction(L, (f)), \
+ lua_pushlightuserdata(L,(u)), \
+ lua_pcall(L,1,0,0))
+
+
+/*
+@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
+** You can rewrite 'log10(x)' as 'log(x, 10)'.
+*/
+#define LUA_COMPAT_LOG10
+
+/*
+@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
+** library. You can rewrite 'loadstring(s)' as 'load(s)'.
+*/
+#define LUA_COMPAT_LOADSTRING
+
+/*
+@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
+*/
+#define LUA_COMPAT_MAXN
+
+/*
+@@ The following macros supply trivial compatibility for some
+** changes in the API. The macros themselves document how to
+** change your code to avoid using them.
+*/
+#define lua_strlen(L,i) lua_rawlen(L, (i))
+
+#define lua_objlen(L,i) lua_rawlen(L, (i))
+
+#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
+
+/*
+@@ LUA_COMPAT_MODULE controls compatibility with previous
+** module functions 'module' (Lua) and 'luaL_register' (C).
+*/
+#define LUA_COMPAT_MODULE
+
+#endif /* } */
+
+
+/*
+@@ LUA_COMPAT_FLOATSTRING makes Lua format integral floats without a
+@@ a float mark ('.0').
+** This macro is not on by default even in compatibility mode,
+** because this is not really an incompatibility.
+*/
+/* #define LUA_COMPAT_FLOATSTRING */
+
+/* }================================================================== */
+
+
+
+/*
+** {==================================================================
+** Configuration for Numbers.
+** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
+** satisfy your needs.
+** ===================================================================
+*/
+
+/*
+@@ LUA_NUMBER is the floating-point type used by Lua.
+@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+@@ over a floating number.
+@@ l_mathlim(x) corrects limit name 'x' to the proper float type
+** by prefixing it with one of FLT/DBL/LDBL.
+@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
+@@ LUA_NUMBER_FMT is the format for writing floats.
+@@ lua_number2str converts a float to a string.
+@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
+@@ l_floor takes the floor of a float.
+@@ lua_str2number converts a decimal numeric string to a number.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define l_floor(x) (l_mathop(floor)(x))
+
+#define lua_number2str(s,sz,n) l_sprintf((s), sz, LUA_NUMBER_FMT, (n))
+
+/*
+@@ lua_numbertointeger converts a float number to an integer, or
+** returns 0 if float is not within the range of a lua_Integer.
+** (The range comparisons are tricky because of rounding. The tests
+** here assume a two-complement representation, where MININTEGER always
+** has an exact representation as a float; MAXINTEGER may not have one,
+** and therefore its conversion to float may have an ill-defined value.)
+*/
+#define lua_numbertointeger(n,p) \
+ ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
+ (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
+ (*(p) = (LUA_INTEGER)(n), 1))
+
+
+/* now the variable definitions */
+
+#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
+
+#define LUA_NUMBER float
+
+#define l_mathlim(n) (FLT_##n)
+
+#define LUAI_UACNUMBER double
+
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_FMT "%.7g"
+
+#define l_mathop(op) op##f
+
+#define lua_str2number(s,p) strtof((s), (p))
+
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
+
+#define LUA_NUMBER long double
+
+#define l_mathlim(n) (LDBL_##n)
+
+#define LUAI_UACNUMBER long double
+
+#define LUA_NUMBER_FRMLEN "L"
+#define LUA_NUMBER_FMT "%.19Lg"
+
+#define l_mathop(op) op##l
+
+#define lua_str2number(s,p) strtold((s), (p))
+
+#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
+
+#define LUA_NUMBER double
+
+#define l_mathlim(n) (DBL_##n)
+
+#define LUAI_UACNUMBER double
+
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_FMT "%.14g"
+
+#define l_mathop(op) op
+
+#define lua_str2number(s,p) strtod((s), (p))
+
+#else /* }{ */
+
+#error "numeric float type not defined"
+
+#endif /* } */
+
+
+
+/*
+@@ LUA_INTEGER is the integer type used by Lua.
+**
+@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
+**
+@@ LUAI_UACINT is the result of an 'usual argument conversion'
+@@ over a lUA_INTEGER.
+@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
+@@ LUA_INTEGER_FMT is the format for writing integers.
+@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
+@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
+@@ lua_integer2str converts an integer to a string.
+*/
+
+
+/* The following definitions are good for most cases here */
+
+#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
+#define lua_integer2str(s,sz,n) l_sprintf((s), sz, LUA_INTEGER_FMT, (n))
+
+#define LUAI_UACINT LUA_INTEGER
+
+/*
+** use LUAI_UACINT here to avoid problems with promotions (which
+** can turn a comparison between unsigneds into a signed comparison)
+*/
+#define LUA_UNSIGNED unsigned LUAI_UACINT
+
+
+/* now the variable definitions */
+
+#if LUA_INT_TYPE == LUA_INT_INT /* { int */
+
+#define LUA_INTEGER int
+#define LUA_INTEGER_FRMLEN ""
+
+#define LUA_MAXINTEGER INT_MAX
+#define LUA_MININTEGER INT_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
+
+#define LUA_INTEGER long
+#define LUA_INTEGER_FRMLEN "l"
+
+#define LUA_MAXINTEGER LONG_MAX
+#define LUA_MININTEGER LONG_MIN
+
+#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
+
+/* use presence of macro LLONG_MAX as proxy for C99 compliance */
+#if defined(LLONG_MAX) /* { */
+/* use ISO C99 stuff */
+
+#define LUA_INTEGER long long
+#define LUA_INTEGER_FRMLEN "ll"
+
+#define LUA_MAXINTEGER LLONG_MAX
+#define LUA_MININTEGER LLONG_MIN
+
+#elif defined(LUA_USE_WINDOWS) /* }{ */
+/* in Windows, can use specific Windows types */
+
+#define LUA_INTEGER __int64
+#define LUA_INTEGER_FRMLEN "I64"
+
+#define LUA_MAXINTEGER _I64_MAX
+#define LUA_MININTEGER _I64_MIN
+
+#else /* }{ */
+
+#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
+ or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
+
+#endif /* } */
+
+#else /* }{ */
+
+#error "numeric integer type not defined"
+
+#endif /* } */
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Dependencies with C99 and other C details
+** ===================================================================
+*/
+
+/*
+@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
+** (All uses in Lua have only one format item.)
+*/
+#if !defined(LUA_USE_C89)
+#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i)
+#else
+#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i))
+#endif
+
+
+/*
+@@ lua_strx2number converts an hexadecimal numeric string to a number.
+** In C99, 'strtod' does that conversion. Otherwise, you can
+** leave 'lua_strx2number' undefined and Lua will provide its own
+** implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_strx2number(s,p) lua_str2number(s,p)
+#endif
+
+
+/*
+@@ lua_number2strx converts a float to an hexadecimal numeric string.
+** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
+** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
+** provide its own implementation.
+*/
+#if !defined(LUA_USE_C89)
+#define lua_number2strx(L,b,sz,f,n) ((void)L, l_sprintf(b,sz,f,n))
+#endif
+
+
+/*
+** 'strtof' and 'opf' variants for math functions are not valid in
+** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
+** availability of these variants. ('math.h' is already included in
+** all files that use these macros.)
+*/
+#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
+#undef l_mathop /* variants not available */
+#undef lua_str2number
+#define l_mathop(op) (lua_Number)op /* no variant */
+#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
+#endif
+
+
+/*
+@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
+** functions. It must be a numerical type; Lua will use 'intptr_t' if
+** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
+** 'intptr_t' in C89)
+*/
+#define LUA_KCONTEXT ptrdiff_t
+
+#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
+ __STDC_VERSION__ >= 199901L
+#include <stdint.h>
+#if defined(INTPTR_MAX) /* even in C99 this type is optional */
+#undef LUA_KCONTEXT
+#define LUA_KCONTEXT intptr_t
+#endif
+#endif
+
+
+/*
+@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
+** Change that if you do not want to use C locales. (Code using this
+** macro must include header 'locale.h'.)
+*/
+#if !defined(lua_getlocaledecpoint)
+#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Language Variations
+** =====================================================================
+*/
+
+/*
+@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
+** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
+** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
+** coercion from strings to numbers.
+*/
+/* #define LUA_NOCVTN2S */
+/* #define LUA_NOCVTS2N */
+
+
+/*
+@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
+** Define it as a help when debugging C code.
+*/
+#if defined(LUA_USE_APICHECK)
+#include <assert.h>
+#define luai_apicheck(l,e) assert(e)
+#endif
+
+/* }================================================================== */
+
+
+/*
+** {==================================================================
+** Macros that affect the API and must be stable (that is, must be the
+** same when you compile Lua and when you compile code that links to
+** Lua). You probably do not want/need to change them.
+** =====================================================================
+*/
+
+/*
+@@ LUAI_MAXSTACK limits the size of the Lua stack.
+** CHANGE it if you need a different limit. This limit is arbitrary;
+** its only purpose is to stop Lua from consuming unlimited stack
+** space (and to reserve some numbers for pseudo-indices).
+*/
+#if LUAI_BITSINT >= 32
+#define LUAI_MAXSTACK 1000000
+#else
+#define LUAI_MAXSTACK 15000
+#endif
+
+
+/*
+@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
+** a Lua state with very fast access.
+** CHANGE it if you need a different size.
+*/
+#define LUA_EXTRASPACE (sizeof(void *))
+
+
+/*
+@@ LUA_IDSIZE gives the maximum size for the description of the source
+@@ of a function in debug information.
+** CHANGE it if you want a different size.
+*/
+#define LUA_IDSIZE 60
+
+
+/*
+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+** CHANGE it if it uses too much C-stack space. (For long double,
+** 'string.format("%.99f", 1e4932)' needs ~5030 bytes, so a
+** smaller buffer would force a memory allocation for each call to
+** 'string.format'.)
+*/
+#if defined(LUA_FLOAT_LONGDOUBLE)
+#define LUAL_BUFFERSIZE 8192
+#else
+#define LUAL_BUFFERSIZE ((int)(0x80 * sizeof(void*) * sizeof(lua_Integer)))
+#endif
+
+/* }================================================================== */
+
+
+/*
+@@ LUA_QL describes how error messages quote program elements.
+** Lua does not use these macros anymore; they are here for
+** compatibility only.
+*/
+#define LUA_QL(x) "'" x "'"
+#define LUA_QS LUA_QL("%s")
+
+
+
+
+/* =================================================================== */
+
+/*
+** Local configuration. You can use this space to add your redefinitions
+** without modifying the main part of the file.
+*/
+
+
+
+
+
+#endif
+
diff --git a/src/external/lua/include/lualib.h b/src/external/lua/include/lualib.h
new file mode 100644
index 00000000..5165c0fb
--- /dev/null
+++ b/src/external/lua/include/lualib.h
@@ -0,0 +1,58 @@
+/*
+** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $
+** Lua standard libraries
+** See Copyright Notice in lua.h
+*/
+
+
+#ifndef lualib_h
+#define lualib_h
+
+#include "lua.h"
+
+
+
+LUAMOD_API int (luaopen_base) (lua_State *L);
+
+#define LUA_COLIBNAME "coroutine"
+LUAMOD_API int (luaopen_coroutine) (lua_State *L);
+
+#define LUA_TABLIBNAME "table"
+LUAMOD_API int (luaopen_table) (lua_State *L);
+
+#define LUA_IOLIBNAME "io"
+LUAMOD_API int (luaopen_io) (lua_State *L);
+
+#define LUA_OSLIBNAME "os"
+LUAMOD_API int (luaopen_os) (lua_State *L);
+
+#define LUA_STRLIBNAME "string"
+LUAMOD_API int (luaopen_string) (lua_State *L);
+
+#define LUA_UTF8LIBNAME "utf8"
+LUAMOD_API int (luaopen_utf8) (lua_State *L);
+
+#define LUA_BITLIBNAME "bit32"
+LUAMOD_API int (luaopen_bit32) (lua_State *L);
+
+#define LUA_MATHLIBNAME "math"
+LUAMOD_API int (luaopen_math) (lua_State *L);
+
+#define LUA_DBLIBNAME "debug"
+LUAMOD_API int (luaopen_debug) (lua_State *L);
+
+#define LUA_LOADLIBNAME "package"
+LUAMOD_API int (luaopen_package) (lua_State *L);
+
+
+/* open all previous libraries */
+LUALIB_API void (luaL_openlibs) (lua_State *L);
+
+
+
+#if !defined(lua_assert)
+#define lua_assert(x) ((void)0)
+#endif
+
+
+#endif
diff --git a/src/external/lua/lib/liblua53.a b/src/external/lua/lib/liblua53.a
new file mode 100644
index 00000000..e51c0c80
--- /dev/null
+++ b/src/external/lua/lib/liblua53.a
Binary files differ
diff --git a/src/external/lua/lib/liblua53dll.a b/src/external/lua/lib/liblua53dll.a
new file mode 100644
index 00000000..32646db3
--- /dev/null
+++ b/src/external/lua/lib/liblua53dll.a
Binary files differ
diff --git a/src/external/pthread/lib/pthreadGC2.dll b/src/external/pthread/lib/pthreadGC2.dll
new file mode 100644
index 00000000..67b9289d
--- /dev/null
+++ b/src/external/pthread/lib/pthreadGC2.dll
Binary files differ
diff --git a/src/gestures.c b/src/gestures.c
deleted file mode 100644
index 57b96bd2..00000000
--- a/src/gestures.c
+++ /dev/null
@@ -1,423 +0,0 @@
-/**********************************************************************************************
-*
-* raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse)
-*
-* Initial design by Marc Palau
-* Redesigned by Albert Martos and Ian Eito
-* Reviewed by 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 GESTURES_STANDALONE // NOTE: To use the gestures module as standalone lib, just uncomment this line
-
-#if defined(GESTURES_STANDALONE)
- #include "gestures.h"
-#else
- #include "raylib.h" // Required for: Vector2, Gestures
-#endif
-
-#include <math.h> // Required for: atan2(), sqrt()
-#include <stdint.h> // Required for: uint64_t
-
-#if defined(_WIN32)
- // Functions required to query time on Windows
- int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
- int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
-#elif defined(__linux)
- #include <sys/time.h> // Required for: timespec
- #include <time.h> // Required for: clock_gettime()
-#endif
-
-//----------------------------------------------------------------------------------
-// Defines and Macros
-//----------------------------------------------------------------------------------
-#define FORCE_TO_SWIPE 0.0005f // Measured in normalized screen units/time
-#define MINIMUM_DRAG 0.015f // Measured in normalized screen units (0.0f to 1.0f)
-#define MINIMUM_PINCH 0.005f // Measured in normalized screen units (0.0f to 1.0f)
-#define TAP_TIMEOUT 300 // Time in milliseconds
-#define PINCH_TIMEOUT 300 // Time in milliseconds
-#define DOUBLETAP_RANGE 0.03f // Measured in normalized screen units (0.0f to 1.0f)
-
-//----------------------------------------------------------------------------------
-// Types and Structures Definition
-//----------------------------------------------------------------------------------
-// ...
-
-//----------------------------------------------------------------------------------
-// Global Variables Definition
-//----------------------------------------------------------------------------------
-
-// Touch gesture variables
-static Vector2 touchDownPosition = { 0.0f, 0.0f };
-static Vector2 touchDownPosition2 = { 0.0f, 0.0f };
-static Vector2 touchDownDragPosition = { 0.0f, 0.0f };
-static Vector2 touchUpPosition = { 0.0f, 0.0f };
-static Vector2 moveDownPosition = { 0.0f, 0.0f };
-static Vector2 moveDownPosition2 = { 0.0f, 0.0f };
-static int numTap = 0;
-
-static int pointCount = 0;
-static int firstTouchId = -1;
-
-static double eventTime = 0.0;
-static double swipeTime = 0.0;
-
-// Hold gesture variables
-static int numHold = 0;
-static float timeHold = 0.0f;
-
-// Drag gesture variables
-static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position)
-static float dragAngle = 0.0f; // DRAG angle (relative to x-axis)
-static float dragDistance = 0.0f; // DRAG distance (from initial touch point to final) (normalized [0..1])
-static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame)
-static bool startMoving = false; // SWIPE used to define when start measuring swipeTime
-
-// Pinch gesture variables
-static Vector2 pinchVector = { 0.0f , 0.0f }; // PINCH vector (between first and second touch points)
-static float pinchAngle = 0.0f; // PINCH angle (relative to x-axis)
-static float pinchDistance = 0.0f; // PINCH displacement distance (normalized [0..1])
-
-// Detected gestures
-static int previousGesture = GESTURE_NONE;
-static int currentGesture = GESTURE_NONE;
-
-// Enabled gestures flags, all gestures enabled by default
-static unsigned int enabledGestures = 0b0000001111111111;
-
-//----------------------------------------------------------------------------------
-// Module specific Functions Declaration
-//----------------------------------------------------------------------------------
-static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition);
-static float Vector2Distance(Vector2 v1, Vector2 v2);
-static double GetCurrentTime(void);
-
-//----------------------------------------------------------------------------------
-// Module Functions Definition
-//----------------------------------------------------------------------------------
-
-// Enable only desired getures to be detected
-void SetGesturesEnabled(unsigned int gestureFlags)
-{
- enabledGestures = gestureFlags;
-}
-
-// Check if a gesture have been detected
-bool IsGestureDetected(int gesture)
-{
- if ((enabledGestures & currentGesture) == gesture) return true;
- else return false;
-}
-
-// Process gesture event and translate it into gestures
-void ProcessGestureEvent(GestureEvent event)
-{
- // Reset required variables
- previousGesture = currentGesture;
-
- pointCount = event.pointCount; // Required on UpdateGestures()
-
- if (pointCount < 2)
- {
- if (event.touchAction == TOUCH_DOWN)
- {
- numTap++; // Tap counter
-
- // Detect GESTURE_DOUBLE_TAP
- if ((currentGesture == GESTURE_NONE) && (numTap >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE))
- {
- currentGesture = GESTURE_DOUBLETAP;
- numTap = 0;
- }
- else // Detect GESTURE_TAP
- {
- numTap = 1;
- currentGesture = GESTURE_TAP;
- }
-
- touchDownPosition = event.position[0];
- touchDownDragPosition = event.position[0];
-
- touchUpPosition = touchDownPosition;
- eventTime = GetCurrentTime();
-
- firstTouchId = event.pointerId[0];
-
- dragVector = (Vector2){ 0.0f, 0.0f };
- }
- else if (event.touchAction == TOUCH_UP)
- {
- if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0];
-
- // NOTE: dragIntensity dependend on the resolution of the screen
- dragDistance = Vector2Distance(touchDownPosition, touchUpPosition);
- dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime));
-
- startMoving = false;
-
- // Detect GESTURE_SWIPE
- if ((dragIntensity > FORCE_TO_SWIPE) && firstTouchId == event.pointerId[0])
- {
- // NOTE: Angle should be inverted in Y
- dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition);
-
- if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right
- else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up
- else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left
- else if ((dragAngle > 210) && (dragAngle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down
- else currentGesture = GESTURE_NONE;
- }
- else
- {
- dragDistance = 0.0f;
- dragIntensity = 0.0f;
- dragAngle = 0.0f;
-
- currentGesture = GESTURE_NONE;
- }
-
- touchDownDragPosition = (Vector2){ 0.0f, 0.0f };
- pointCount = 0;
- }
- else if (event.touchAction == TOUCH_MOVE)
- {
- if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime();
-
- if (!startMoving)
- {
- swipeTime = GetCurrentTime();
- startMoving = true;
- }
-
- moveDownPosition = event.position[0];
-
- if (currentGesture == GESTURE_HOLD)
- {
- if (numHold == 1) touchDownPosition = event.position[0];
-
- numHold = 2;
-
- // Detect GESTURE_DRAG
- if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG)
- {
- eventTime = GetCurrentTime();
- currentGesture = GESTURE_DRAG;
- }
- }
-
- dragVector.x = moveDownPosition.x - touchDownDragPosition.x;
- dragVector.y = moveDownPosition.y - touchDownDragPosition.y;
- }
- }
- else // Two touch points
- {
- if (event.touchAction == TOUCH_DOWN)
- {
- touchDownPosition = event.position[0];
- touchDownPosition2 = event.position[1];
-
- //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2);
-
- pinchVector.x = touchDownPosition2.x - touchDownPosition.x;
- pinchVector.y = touchDownPosition2.y - touchDownPosition.y;
-
- currentGesture = GESTURE_HOLD;
- timeHold = GetCurrentTime();
- }
- else if (event.touchAction == TOUCH_MOVE)
- {
- pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2);
-
- touchDownPosition = moveDownPosition;
- touchDownPosition2 = moveDownPosition2;
-
- moveDownPosition = event.position[0];
- moveDownPosition2 = event.position[1];
-
- pinchVector.x = moveDownPosition2.x - moveDownPosition.x;
- pinchVector.y = moveDownPosition2.y - moveDownPosition.y;
-
- if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH))
- {
- if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN;
- else currentGesture = GESTURE_PINCH_OUT;
- }
- else
- {
- currentGesture = GESTURE_HOLD;
- timeHold = GetCurrentTime();
- }
-
- // NOTE: Angle should be inverted in Y
- pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2);
- }
- else if (event.touchAction == TOUCH_UP)
- {
- pinchDistance = 0.0f;
- pinchAngle = 0.0f;
- pinchVector = (Vector2){ 0.0f, 0.0f };
- pointCount = 0;
-
- currentGesture = GESTURE_NONE;
- }
- }
-}
-
-// Update gestures detected (must be called every frame)
-void UpdateGestures(void)
-{
- // NOTE: Gestures are processed through system callbacks on touch events
-
- // Detect GESTURE_HOLD
- if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && (pointCount < 2))
- {
- currentGesture = GESTURE_HOLD;
- timeHold = GetCurrentTime();
- }
-
- if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2))
- {
- currentGesture = GESTURE_HOLD;
- timeHold = GetCurrentTime();
- numHold = 1;
- }
-
- // Detect GESTURE_NONE
- if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN))
- {
- currentGesture = GESTURE_NONE;
- }
-}
-
-// Get number of touch points
-int GetTouchPointsCount(void)
-{
- // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called
-
- return pointCount;
-}
-
-// Get latest detected gesture
-int GetGestureDetected(void)
-{
- // Get current gesture only if enabled
- return (enabledGestures & currentGesture);
-}
-
-// Hold time measured in ms
-float GetGestureHoldDuration(void)
-{
- // NOTE: time is calculated on current gesture HOLD
-
- float time = 0.0f;
-
- if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold;
-
- return time;
-}
-
-// Get drag vector (between initial touch point to current)
-Vector2 GetGestureDragVector(void)
-{
- // NOTE: drag vector is calculated on one touch points TOUCH_MOVE
-
- return dragVector;
-}
-
-// Get drag angle
-// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
-float GetGestureDragAngle(void)
-{
- // NOTE: drag angle is calculated on one touch points TOUCH_UP
-
- return dragAngle;
-}
-
-// Get distance between two pinch points
-Vector2 GetGesturePinchVector(void)
-{
- // NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index)
- // NOTE: pinch distance is calculated on two touch points TOUCH_MOVE
-
- return pinchVector;
-}
-
-// Get angle beween two pinch points
-// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
-float GetGesturePinchAngle(void)
-{
- // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE
-
- return pinchAngle;
-}
-
-//----------------------------------------------------------------------------------
-// Module specific Functions Definition
-//----------------------------------------------------------------------------------
-
-// Returns angle from two-points vector with X-axis
-static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition)
-{
- float angle;
-
- angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x);
- angle *= RAD2DEG;
-
- if (angle < 0) angle += 360.0f;
-
- return angle;
-}
-
-// Calculate distance between two Vector2
-static float Vector2Distance(Vector2 v1, Vector2 v2)
-{
- float result;
-
- float dx = v2.x - v1.x;
- float dy = v2.y - v1.y;
-
- result = sqrt(dx*dx + dy*dy);
-
- return result;
-}
-
-// Time measure returned are milliseconds
-static double GetCurrentTime(void)
-{
- double time = 0;
-
-#if defined(_WIN32)
- unsigned long long int clockFrequency, currentTime;
-
- QueryPerformanceFrequency(&clockFrequency);
- QueryPerformanceCounter(&currentTime);
-
- time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds
-#endif
-
-#if defined(__linux)
- // NOTE: Only for Linux-based systems
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds
-
- time = ((double)nowTime/1000000.0); // Time in miliseconds
-#endif
-
- return time;
-}
diff --git a/src/gestures.h b/src/gestures.h
index 912d0b92..481ef317 100644
--- a/src/gestures.h
+++ b/src/gestures.h
@@ -1,8 +1,21 @@
/**********************************************************************************************
*
-* raylib Gestures System - Gestures Detection and Usage Functions (Android and HTML5)
+* raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse)
*
-* Copyright (c) 2015 Marc Palau and Ramon Santamaria
+* #define GESTURES_IMPLEMENTATION
+* Generates the implementation of the library into the included file.
+* If not defined, the library is in header only mode and can be included in other headers
+* or source files without problems. But only ONE file should hold the implementation.
+*
+* #define GESTURES_STANDALONE
+* If defined, the library can be used as standalone to process gesture events with
+* no external dependencies.
+*
+* NOTE: Memory footprint of this library is aproximately 128 bytes
+*
+* Initial design by Marc Palau (2014)
+* Redesigned by Albert Martos and Ian Eito (2015)
+* Reviewed by Ramon Santamaria (2015-2016)
*
* 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.
@@ -28,9 +41,6 @@
#define PI 3.14159265358979323846
#endif
-#define DEG2RAD (PI / 180.0f)
-#define RAD2DEG (180.0f / PI)
-
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -40,32 +50,34 @@
// Types and Structures Definition
// NOTE: Below types are required for GESTURES_STANDALONE usage
//----------------------------------------------------------------------------------
-#ifndef __cplusplus
- // Boolean type
- typedef enum { false, true } bool;
-#endif
+#if defined(GESTURES_STANDALONE)
+ #ifndef __cplusplus
+ // Boolean type
+ typedef enum { false, true } bool;
+ #endif
+
+ // Vector2 type
+ typedef struct Vector2 {
+ float x;
+ float y;
+ } Vector2;
-// Vector2 type
-typedef struct Vector2 {
- float x;
- float y;
-} Vector2;
-
-// Gestures type
-// NOTE: It could be used as flags to enable only some gestures
-typedef enum {
- GESTURE_NONE = 1,
- GESTURE_TAP = 2,
- GESTURE_DOUBLETAP = 4,
- GESTURE_HOLD = 8,
- GESTURE_DRAG = 16,
- GESTURE_SWIPE_RIGHT = 32,
- GESTURE_SWIPE_LEFT = 64,
- GESTURE_SWIPE_UP = 128,
- GESTURE_SWIPE_DOWN = 256,
- GESTURE_PINCH_IN = 512,
- GESTURE_PINCH_OUT = 1024
-} Gestures;
+ // Gestures type
+ // NOTE: It could be used as flags to enable only some gestures
+ typedef enum {
+ GESTURE_NONE = 1,
+ GESTURE_TAP = 2,
+ GESTURE_DOUBLETAP = 4,
+ GESTURE_HOLD = 8,
+ GESTURE_DRAG = 16,
+ GESTURE_SWIPE_RIGHT = 32,
+ GESTURE_SWIPE_LEFT = 64,
+ GESTURE_SWIPE_UP = 128,
+ GESTURE_SWIPE_DOWN = 256,
+ GESTURE_PINCH_IN = 512,
+ GESTURE_PINCH_OUT = 1024
+ } Gestures;
+#endif
typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
@@ -90,22 +102,422 @@ extern "C" { // Prevents name mangling of functions
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
-void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
-bool IsGestureDetected(int gesture); // Check if a gesture have been detected
void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
void UpdateGestures(void); // Update gestures detected (must be called every frame)
-int GetTouchPointsCount(void); // Get touch points count
+#if defined(GESTURES_STANDALONE)
+void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
+bool IsGestureDetected(int gesture); // Check if a gesture have been detected
int GetGestureDetected(void); // Get latest detected gesture
+int GetTouchPointsCount(void); // Get touch points count
float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
Vector2 GetGestureDragVector(void); // Get gesture drag vector
float GetGestureDragAngle(void); // Get gesture drag angle
Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
float GetGesturePinchAngle(void); // Get gesture pinch angle
-
+#endif
#ifdef __cplusplus
}
#endif
#endif // GESTURES_H
+
+/***********************************************************************************
+*
+* GESTURES IMPLEMENTATION
+*
+************************************************************************************/
+
+#if defined(GESTURES_IMPLEMENTATION)
+
+#include <math.h> // Required for: atan2(), sqrt()
+#include <stdint.h> // Required for: uint64_t
+
+#if defined(_WIN32)
+ // Functions required to query time on Windows
+ int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
+ int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
+#elif defined(__linux)
+ #include <sys/time.h> // Required for: timespec
+ #include <time.h> // Required for: clock_gettime()
+#endif
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+#define FORCE_TO_SWIPE 0.0005f // Measured in normalized screen units/time
+#define MINIMUM_DRAG 0.015f // Measured in normalized screen units (0.0f to 1.0f)
+#define MINIMUM_PINCH 0.005f // Measured in normalized screen units (0.0f to 1.0f)
+#define TAP_TIMEOUT 300 // Time in milliseconds
+#define PINCH_TIMEOUT 300 // Time in milliseconds
+#define DOUBLETAP_RANGE 0.03f // Measured in normalized screen units (0.0f to 1.0f)
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+// ...
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+
+// Touch gesture variables
+static Vector2 touchDownPosition = { 0.0f, 0.0f };
+static Vector2 touchDownPosition2 = { 0.0f, 0.0f };
+static Vector2 touchDownDragPosition = { 0.0f, 0.0f };
+static Vector2 touchUpPosition = { 0.0f, 0.0f };
+static Vector2 moveDownPosition = { 0.0f, 0.0f };
+static Vector2 moveDownPosition2 = { 0.0f, 0.0f };
+
+static int pointCount = 0; // Touch points counter
+static int firstTouchId = -1; // Touch id for first touch point
+static double eventTime = 0.0; // Time stamp when an event happened
+
+// Tap gesture variables
+static int tapCounter = 0; // TAP counter (one tap implies TOUCH_DOWN and TOUCH_UP actions)
+
+// Hold gesture variables
+static bool resetHold = false; // HOLD reset to get first touch point again
+static float timeHold = 0.0f; // HOLD duration in milliseconds
+
+// Drag gesture variables
+static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position)
+static float dragAngle = 0.0f; // DRAG angle (relative to x-axis)
+static float dragDistance = 0.0f; // DRAG distance (from initial touch point to final) (normalized [0..1])
+static float dragIntensity = 0.0f; // DRAG intensity, how far why did the DRAG (pixels per frame)
+
+// Swipe gestures variables
+static bool startMoving = false; // SWIPE used to define when start measuring swipeTime
+static double swipeTime = 0.0; // SWIPE time to calculate drag intensity
+
+// Pinch gesture variables
+static Vector2 pinchVector = { 0.0f , 0.0f }; // PINCH vector (between first and second touch points)
+static float pinchAngle = 0.0f; // PINCH angle (relative to x-axis)
+static float pinchDistance = 0.0f; // PINCH displacement distance (normalized [0..1])
+
+static int currentGesture = GESTURE_NONE; // Current detected gesture
+
+// Enabled gestures flags, all gestures enabled by default
+static unsigned int enabledGestures = 0b0000001111111111;
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Declaration
+//----------------------------------------------------------------------------------
+static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition);
+static float Vector2Distance(Vector2 v1, Vector2 v2);
+static double GetCurrentTime(void);
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition
+//----------------------------------------------------------------------------------
+
+// Enable only desired getures to be detected
+void SetGesturesEnabled(unsigned int gestureFlags)
+{
+ enabledGestures = gestureFlags;
+}
+
+// Check if a gesture have been detected
+bool IsGestureDetected(int gesture)
+{
+ if ((enabledGestures & currentGesture) == gesture) return true;
+ else return false;
+}
+
+// Process gesture event and translate it into gestures
+void ProcessGestureEvent(GestureEvent event)
+{
+ // Reset required variables
+ pointCount = event.pointCount; // Required on UpdateGestures()
+
+ if (pointCount < 2)
+ {
+ if (event.touchAction == TOUCH_DOWN)
+ {
+ tapCounter++; // Tap counter
+
+ // Detect GESTURE_DOUBLE_TAP
+ if ((currentGesture == GESTURE_NONE) && (tapCounter >= 2) && ((GetCurrentTime() - eventTime) < TAP_TIMEOUT) && (Vector2Distance(touchDownPosition, event.position[0]) < DOUBLETAP_RANGE))
+ {
+ currentGesture = GESTURE_DOUBLETAP;
+ tapCounter = 0;
+ }
+ else // Detect GESTURE_TAP
+ {
+ tapCounter = 1;
+ currentGesture = GESTURE_TAP;
+ }
+
+ touchDownPosition = event.position[0];
+ touchDownDragPosition = event.position[0];
+
+ touchUpPosition = touchDownPosition;
+ eventTime = GetCurrentTime();
+
+ firstTouchId = event.pointerId[0];
+
+ dragVector = (Vector2){ 0.0f, 0.0f };
+ }
+ else if (event.touchAction == TOUCH_UP)
+ {
+ if (currentGesture == GESTURE_DRAG) touchUpPosition = event.position[0];
+
+ // NOTE: dragIntensity dependend on the resolution of the screen
+ dragDistance = Vector2Distance(touchDownPosition, touchUpPosition);
+ dragIntensity = dragDistance/(float)((GetCurrentTime() - swipeTime));
+
+ startMoving = false;
+
+ // Detect GESTURE_SWIPE
+ if ((dragIntensity > FORCE_TO_SWIPE) && (firstTouchId == event.pointerId[0]))
+ {
+ // NOTE: Angle should be inverted in Y
+ dragAngle = 360.0f - Vector2Angle(touchDownPosition, touchUpPosition);
+
+ if ((dragAngle < 30) || (dragAngle > 330)) currentGesture = GESTURE_SWIPE_RIGHT; // Right
+ else if ((dragAngle > 30) && (dragAngle < 120)) currentGesture = GESTURE_SWIPE_UP; // Up
+ else if ((dragAngle > 120) && (dragAngle < 210)) currentGesture = GESTURE_SWIPE_LEFT; // Left
+ else if ((dragAngle > 210) && (dragAngle < 300)) currentGesture = GESTURE_SWIPE_DOWN; // Down
+ else currentGesture = GESTURE_NONE;
+ }
+ else
+ {
+ dragDistance = 0.0f;
+ dragIntensity = 0.0f;
+ dragAngle = 0.0f;
+
+ currentGesture = GESTURE_NONE;
+ }
+
+ touchDownDragPosition = (Vector2){ 0.0f, 0.0f };
+ pointCount = 0;
+ }
+ else if (event.touchAction == TOUCH_MOVE)
+ {
+ if (currentGesture == GESTURE_DRAG) eventTime = GetCurrentTime();
+
+ if (!startMoving)
+ {
+ swipeTime = GetCurrentTime();
+ startMoving = true;
+ }
+
+ moveDownPosition = event.position[0];
+
+ if (currentGesture == GESTURE_HOLD)
+ {
+ if (resetHold) touchDownPosition = event.position[0];
+
+ resetHold = false;
+
+ // Detect GESTURE_DRAG
+ if (Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_DRAG)
+ {
+ eventTime = GetCurrentTime();
+ currentGesture = GESTURE_DRAG;
+ }
+ }
+
+ dragVector.x = moveDownPosition.x - touchDownDragPosition.x;
+ dragVector.y = moveDownPosition.y - touchDownDragPosition.y;
+ }
+ }
+ else // Two touch points
+ {
+ if (event.touchAction == TOUCH_DOWN)
+ {
+ touchDownPosition = event.position[0];
+ touchDownPosition2 = event.position[1];
+
+ //pinchDistance = Vector2Distance(touchDownPosition, touchDownPosition2);
+
+ pinchVector.x = touchDownPosition2.x - touchDownPosition.x;
+ pinchVector.y = touchDownPosition2.y - touchDownPosition.y;
+
+ currentGesture = GESTURE_HOLD;
+ timeHold = GetCurrentTime();
+ }
+ else if (event.touchAction == TOUCH_MOVE)
+ {
+ pinchDistance = Vector2Distance(moveDownPosition, moveDownPosition2);
+
+ touchDownPosition = moveDownPosition;
+ touchDownPosition2 = moveDownPosition2;
+
+ moveDownPosition = event.position[0];
+ moveDownPosition2 = event.position[1];
+
+ pinchVector.x = moveDownPosition2.x - moveDownPosition.x;
+ pinchVector.y = moveDownPosition2.y - moveDownPosition.y;
+
+ if ((Vector2Distance(touchDownPosition, moveDownPosition) >= MINIMUM_PINCH) || (Vector2Distance(touchDownPosition2, moveDownPosition2) >= MINIMUM_PINCH))
+ {
+ if ((Vector2Distance(moveDownPosition, moveDownPosition2) - pinchDistance) < 0) currentGesture = GESTURE_PINCH_IN;
+ else currentGesture = GESTURE_PINCH_OUT;
+ }
+ else
+ {
+ currentGesture = GESTURE_HOLD;
+ timeHold = GetCurrentTime();
+ }
+
+ // NOTE: Angle should be inverted in Y
+ pinchAngle = 360.0f - Vector2Angle(moveDownPosition, moveDownPosition2);
+ }
+ else if (event.touchAction == TOUCH_UP)
+ {
+ pinchDistance = 0.0f;
+ pinchAngle = 0.0f;
+ pinchVector = (Vector2){ 0.0f, 0.0f };
+ pointCount = 0;
+
+ currentGesture = GESTURE_NONE;
+ }
+ }
+}
+
+// Update gestures detected (must be called every frame)
+void UpdateGestures(void)
+{
+ // NOTE: Gestures are processed through system callbacks on touch events
+
+ // Detect GESTURE_HOLD
+ if (((currentGesture == GESTURE_TAP) || (currentGesture == GESTURE_DOUBLETAP)) && (pointCount < 2))
+ {
+ currentGesture = GESTURE_HOLD;
+ timeHold = GetCurrentTime();
+ }
+
+ if (((GetCurrentTime() - eventTime) > TAP_TIMEOUT) && (currentGesture == GESTURE_DRAG) && (pointCount < 2))
+ {
+ currentGesture = GESTURE_HOLD;
+ timeHold = GetCurrentTime();
+ resetHold = true;
+ }
+
+ // Detect GESTURE_NONE
+ if ((currentGesture == GESTURE_SWIPE_RIGHT) || (currentGesture == GESTURE_SWIPE_UP) || (currentGesture == GESTURE_SWIPE_LEFT) || (currentGesture == GESTURE_SWIPE_DOWN))
+ {
+ currentGesture = GESTURE_NONE;
+ }
+}
+
+// Get number of touch points
+int GetTouchPointsCount(void)
+{
+ // NOTE: point count is calculated when ProcessGestureEvent(GestureEvent event) is called
+
+ return pointCount;
+}
+
+// Get latest detected gesture
+int GetGestureDetected(void)
+{
+ // Get current gesture only if enabled
+ return (enabledGestures & currentGesture);
+}
+
+// Hold time measured in ms
+float GetGestureHoldDuration(void)
+{
+ // NOTE: time is calculated on current gesture HOLD
+
+ float time = 0.0f;
+
+ if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold;
+
+ return time;
+}
+
+// Get drag vector (between initial touch point to current)
+Vector2 GetGestureDragVector(void)
+{
+ // NOTE: drag vector is calculated on one touch points TOUCH_MOVE
+
+ return dragVector;
+}
+
+// Get drag angle
+// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
+float GetGestureDragAngle(void)
+{
+ // NOTE: drag angle is calculated on one touch points TOUCH_UP
+
+ return dragAngle;
+}
+
+// Get distance between two pinch points
+Vector2 GetGesturePinchVector(void)
+{
+ // NOTE: The position values used for pinchDistance are not modified like the position values of [core.c]-->GetTouchPosition(int index)
+ // NOTE: pinch distance is calculated on two touch points TOUCH_MOVE
+
+ return pinchVector;
+}
+
+// Get angle beween two pinch points
+// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
+float GetGesturePinchAngle(void)
+{
+ // NOTE: pinch angle is calculated on two touch points TOUCH_MOVE
+
+ return pinchAngle;
+}
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
+
+// Returns angle from two-points vector with X-axis
+static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition)
+{
+ float angle;
+
+ angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI);
+
+ if (angle < 0) angle += 360.0f;
+
+ return angle;
+}
+
+// Calculate distance between two Vector2
+static float Vector2Distance(Vector2 v1, Vector2 v2)
+{
+ float result;
+
+ float dx = v2.x - v1.x;
+ float dy = v2.y - v1.y;
+
+ result = sqrt(dx*dx + dy*dy);
+
+ return result;
+}
+
+// Time measure returned are milliseconds
+static double GetCurrentTime(void)
+{
+ double time = 0;
+
+#if defined(_WIN32)
+ unsigned long long int clockFrequency, currentTime;
+
+ QueryPerformanceFrequency(&clockFrequency);
+ QueryPerformanceCounter(&currentTime);
+
+ time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds
+#endif
+
+#if defined(__linux)
+ // NOTE: Only for Linux-based systems
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time in nanoseconds
+
+ time = ((double)nowTime/1000000.0); // Time in miliseconds
+#endif
+
+ return time;
+}
+
+#endif // GESTURES_IMPLEMENTATION
diff --git a/src/models.c b/src/models.c
index b194a0db..822da6e9 100644
--- a/src/models.c
+++ b/src/models.c
@@ -66,7 +66,7 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
//----------------------------------------------------------------------------------
// Draw a line in 3D world space
-void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color)
+void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color)
{
rlBegin(RL_LINES);
rlColor4ub(color.r, color.g, color.b, color.a);
@@ -76,19 +76,19 @@ void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color)
}
// Draw a circle in 3D world space
-void Draw3DCircle(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color)
+void DrawCircle3D(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color)
{
rlPushMatrix();
rlTranslatef(center.x, center.y, center.z);
rlRotatef(rotationAngle, rotation.x, rotation.y, rotation.z);
-
+
rlBegin(RL_LINES);
for (int i = 0; i < 360; i += 10)
{
rlColor4ub(color.r, color.g, color.b, color.a);
-
+
rlVertex3f(sin(DEG2RAD*i)*radius, cos(DEG2RAD*i)*radius, 0.0f);
- rlVertex3f(sin(DEG2RAD*(i + 10)) * radius, cos(DEG2RAD*(i + 10)) * radius, 0.0f);
+ rlVertex3f(sin(DEG2RAD*(i + 10))*radius, cos(DEG2RAD*(i + 10))*radius, 0.0f);
}
rlEnd();
rlPopMatrix();
@@ -270,25 +270,25 @@ void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float hei
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z+length/2); // Top Left Of The Texture and Quad
// Back Face
- rlNormal3f( 0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer
+ rlNormal3f(0.0f, 0.0f,-1.0f); // Normal Pointing Away From Viewer
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z-length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Left Of The Texture and Quad
// Top Face
- rlNormal3f( 0.0f, 1.0f, 0.0f); // Normal Pointing Up
+ rlNormal3f(0.0f, 1.0f, 0.0f); // Normal Pointing Up
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x-width/2, y+height/2, z-length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x-width/2, y+height/2, z+length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad
// Bottom Face
- rlNormal3f( 0.0f,-1.0f, 0.0f); // Normal Pointing Down
+ rlNormal3f(0.0f,-1.0f, 0.0f); // Normal Pointing Down
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x-width/2, y-height/2, z-length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Top Left Of The Texture and Quad
rlTexCoord2f(0.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z+length/2); // Bottom Left Of The Texture and Quad
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x-width/2, y-height/2, z+length/2); // Bottom Right Of The Texture and Quad
// Right face
- rlNormal3f( 1.0f, 0.0f, 0.0f); // Normal Pointing Right
+ rlNormal3f(1.0f, 0.0f, 0.0f); // Normal Pointing Right
rlTexCoord2f(1.0f, 0.0f); rlVertex3f(x+width/2, y-height/2, z-length/2); // Bottom Right Of The Texture and Quad
rlTexCoord2f(1.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z-length/2); // Top Right Of The Texture and Quad
rlTexCoord2f(0.0f, 1.0f); rlVertex3f(x+width/2, y+height/2, z+length/2); // Top Left Of The Texture and Quad
@@ -325,25 +325,25 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
{
for (int j = 0; j < slices; j++)
{
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)),
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
- cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)),
+ cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*(j*360/slices)),
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*(j*360/slices)));
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)),
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
- cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i))) * sin(DEG2RAD*((j+1)*360/slices)),
+ cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i)))*sin(DEG2RAD*((j+1)*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i))) * cos(DEG2RAD*((j+1)*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)),
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i)))*cos(DEG2RAD*((j+1)*360/slices)));
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)));
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
}
}
rlEnd();
@@ -364,26 +364,26 @@ void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Col
{
for (int j = 0; j < slices; j++)
{
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)),
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
- cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)),
+ cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)));
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*((j+1)*360/slices)),
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*((j+1)*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*((j+1)*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*(j*360/slices)),
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*((j+1)*360/slices)));
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*(j*360/slices)));
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * sin(DEG2RAD*(j*360/slices)),
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*(i+1))),
- cos(DEG2RAD*(270+(180/(rings + 1))*(i+1))) * cos(DEG2RAD*(j*360/slices)));
- rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i)) * sin(DEG2RAD*(j*360/slices)),
+ cos(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cos(DEG2RAD*(j*360/slices)));
+ rlVertex3f(cos(DEG2RAD*(270+(180/(rings + 1))*i))*sin(DEG2RAD*(j*360/slices)),
sin(DEG2RAD*(270+(180/(rings + 1))*i)),
- cos(DEG2RAD*(270+(180/(rings + 1))*i)) * cos(DEG2RAD*(j*360/slices)));
+ cos(DEG2RAD*(270+(180/(rings + 1))*i))*cos(DEG2RAD*(j*360/slices)));
}
}
rlEnd();
@@ -407,21 +407,21 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
// Draw Body -------------------------------------------------------------------------------------
for (int i = 0; i < 360; i += 360/sides)
{
- rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom); //Bottom Right
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); //Top Right
+ rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); //Bottom Left
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom); //Bottom Right
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); //Top Right
- rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop); //Top Left
- rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom); //Bottom Left
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop); //Top Right
+ rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop); //Top Left
+ rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom); //Bottom Left
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop); //Top Right
}
// Draw Cap --------------------------------------------------------------------------------------
for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(0, height, 0);
- rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop);
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop);
+ rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop);
}
}
else
@@ -430,8 +430,8 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(0, height, 0);
- rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
}
}
@@ -439,8 +439,8 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
for (int i = 0; i < 360; i += 360/sides)
{
rlVertex3f(0, 0, 0);
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
- rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
+ rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
}
rlEnd();
rlPopMatrix();
@@ -460,17 +460,17 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
for (int i = 0; i < 360; i += 360/sides)
{
- rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusBottom, 0, cos(DEG2RAD*(i+360/sides)) * radiusBottom);
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusBottom, 0, cos(DEG2RAD*(i+360/sides))*radiusBottom);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop);
- rlVertex3f(sin(DEG2RAD*(i+360/sides)) * radiusTop, height, cos(DEG2RAD*(i+360/sides)) * radiusTop);
- rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop);
+ rlVertex3f(sin(DEG2RAD*(i+360/sides))*radiusTop, height, cos(DEG2RAD*(i+360/sides))*radiusTop);
+ rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop);
- rlVertex3f(sin(DEG2RAD*i) * radiusTop, height, cos(DEG2RAD*i) * radiusTop);
- rlVertex3f(sin(DEG2RAD*i) * radiusBottom, 0, cos(DEG2RAD*i) * radiusBottom);
+ rlVertex3f(sin(DEG2RAD*i)*radiusTop, height, cos(DEG2RAD*i)*radiusTop);
+ rlVertex3f(sin(DEG2RAD*i)*radiusBottom, 0, cos(DEG2RAD*i)*radiusBottom);
}
rlEnd();
rlPopMatrix();
@@ -516,7 +516,7 @@ void DrawRay(Ray ray, Color color)
// Draw a grid centered at (0, 0, 0)
void DrawGrid(int slices, float spacing)
{
- int halfSlices = slices / 2;
+ int halfSlices = slices/2;
rlBegin(RL_LINES);
for (int i = -halfSlices; i <= halfSlices; i++)
@@ -577,22 +577,30 @@ void DrawLight(Light light)
{
case LIGHT_POINT:
{
- DrawSphereWires(light->position, 0.3f*light->intensity, 4, 8, (light->enabled ? light->diffuse : BLACK));
- Draw3DCircle(light->position, light->radius, 0.0f, (Vector3){ 0, 0, 0 }, (light->enabled ? light->diffuse : BLACK));
- Draw3DCircle(light->position, light->radius, 90.0f, (Vector3){ 1, 0, 0 }, (light->enabled ? light->diffuse : BLACK));
- Draw3DCircle(light->position, light->radius, 90.0f, (Vector3){ 0, 1, 0 }, (light->enabled ? light->diffuse : BLACK));
+ DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY));
+
+ DrawCircle3D(light->position, light->radius, 0.0f, (Vector3){ 0, 0, 0 }, (light->enabled ? light->diffuse : GRAY));
+ DrawCircle3D(light->position, light->radius, 90.0f, (Vector3){ 1, 0, 0 }, (light->enabled ? light->diffuse : GRAY));
+ DrawCircle3D(light->position, light->radius, 90.0f, (Vector3){ 0, 1, 0 }, (light->enabled ? light->diffuse : GRAY));
} break;
case LIGHT_DIRECTIONAL:
- {
- Draw3DLine(light->position, light->target, (light->enabled ? light->diffuse : BLACK));
- DrawSphereWires(light->position, 0.3f*light->intensity, 4, 8, (light->enabled ? light->diffuse : BLACK));
- DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : BLACK));
+ {
+ DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY));
+
+ DrawSphereWires(light->position, 0.3f*light->intensity, 8, 8, (light->enabled ? light->diffuse : GRAY));
+ DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY));
} break;
case LIGHT_SPOT:
- {
- Draw3DLine(light->position, light->target, (light->enabled ? light->diffuse : BLACK));
- DrawCylinderWires(light->position, 0.0f, 0.3f*light->coneAngle/50, 0.6f, 5, (light->enabled ? light->diffuse : BLACK));
- DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : BLACK));
+ {
+ DrawLine3D(light->position, light->target, (light->enabled ? light->diffuse : GRAY));
+
+ Vector3 dir = VectorSubtract(light->target, light->position);
+ VectorNormalize(&dir);
+
+ DrawCircle3D(light->position, 0.5f, 0.0f, dir, (light->enabled ? light->diffuse : GRAY));
+
+ //DrawCylinderWires(light->position, 0.0f, 0.3f*light->coneAngle/50, 0.6f, 5, (light->enabled ? light->diffuse : GRAY));
+ DrawCubeWires(light->target, 0.3f, 0.3f, 0.3f, (light->enabled ? light->diffuse : GRAY));
} break;
default: break;
}
@@ -602,7 +610,7 @@ void DrawLight(Light light)
Model LoadModel(const char *fileName)
{
Model model = { 0 };
-
+
// TODO: Initialize default data for model in case loading fails, maybe a cube?
if (strcmp(GetExtension(fileName), "obj") == 0) model.mesh = LoadOBJ(fileName);
@@ -612,7 +620,7 @@ Model LoadModel(const char *fileName)
else
{
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
-
+
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
}
@@ -626,12 +634,12 @@ Model LoadModelEx(Mesh data, bool dynamic)
Model model = { 0 };
model.mesh = data;
-
+
rlglLoadMesh(&model.mesh, dynamic); // Upload vertex data to GPU
-
+
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
-
+
return model;
}
@@ -723,11 +731,11 @@ Model LoadModelFromRES(const char *rresName, int resId)
Model LoadHeightmap(Image heightmap, Vector3 size)
{
Model model = { 0 };
-
+
model.mesh = GenMeshHeightmap(heightmap, size);
-
+
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
-
+
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
@@ -738,11 +746,11 @@ Model LoadHeightmap(Image heightmap, Vector3 size)
Model LoadCubicmap(Image cubicmap)
{
Model model = { 0 };
-
+
model.mesh = GenMeshCubicmap(cubicmap, (Vector3){ 1.0f, 1.5f, 1.0f });
-
+
rlglLoadMesh(&model.mesh, false); // Upload vertex data to GPU (static model)
-
+
model.transform = MatrixIdentity();
model.material = LoadDefaultMaterial();
@@ -755,7 +763,7 @@ void UnloadModel(Model model)
rlglUnloadMesh(&model.mesh);
UnloadMaterial(model.material);
-
+
TraceLog(INFO, "Unloaded model data from RAM and VRAM");
}
@@ -763,10 +771,10 @@ void UnloadModel(Model model)
Material LoadMaterial(const char *fileName)
{
Material material = { 0 };
-
+
if (strcmp(GetExtension(fileName), "mtl") == 0) material = LoadMTL(fileName);
else TraceLog(WARNING, "[%s] Material extension not recognized, it can't be loaded", fileName);
-
+
return material;
}
@@ -774,7 +782,7 @@ Material LoadMaterial(const char *fileName)
Material LoadDefaultMaterial(void)
{
Material material = { 0 };
-
+
material.shader = GetDefaultShader();
material.texDiffuse = GetDefaultTexture(); // White texture (1x1 pixel)
//material.texNormal; // NOTE: By default, not set
@@ -783,9 +791,9 @@ Material LoadDefaultMaterial(void)
material.colDiffuse = WHITE; // Diffuse color
material.colAmbient = WHITE; // Ambient color
material.colSpecular = WHITE; // Specular color
-
+
material.glossiness = 100.0f; // Glossiness level
-
+
return material;
}
@@ -794,7 +802,7 @@ Material LoadDefaultMaterial(void)
Material LoadStandardMaterial(void)
{
Material material = LoadDefaultMaterial();
-
+
material.shader = GetStandardShader();
return material;
@@ -812,12 +820,12 @@ void UnloadMaterial(Material material)
static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
{
#define GRAY_VALUE(c) ((c.r+c.g+c.b)/3)
-
+
Mesh mesh = { 0 };
int mapX = heightmap.width;
int mapZ = heightmap.height;
-
+
Color *pixels = GetImageData(heightmap);
// NOTE: One vertex per pixel
@@ -908,7 +916,7 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
trisCounter += 2;
}
}
-
+
free(pixels);
return mesh;
@@ -919,9 +927,9 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
Mesh mesh = { 0 };
Color *cubicmapPixels = GetImageData(cubicmap);
-
- int mapWidth = cubicmap.width*(int)cubeSize.x;
- int mapHeight = cubicmap.height*(int)cubeSize.z;
+
+ int mapWidth = cubicmap.width;
+ int mapHeight = cubicmap.height;
// NOTE: Max possible number of triangles numCubes * (12 triangles by cube)
int maxTriangles = cubicmap.width*cubicmap.height*12;
@@ -961,19 +969,19 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
RectangleF topTexUV = { 0.0f, 0.5f, 0.5f, 0.5f };
RectangleF bottomTexUV = { 0.5f, 0.5f, 0.5f, 0.5f };
- for (int z = 0; z < mapHeight; z += cubeSize.z)
+ for (int z = 0; z < mapHeight; ++z)
{
- for (int x = 0; x < mapWidth; x += cubeSize.x)
+ for (int x = 0; x < mapWidth; ++x)
{
// Define the 8 vertex of the cube, we will combine them accordingly later...
- Vector3 v1 = { x - w/2, h2, z - h/2 };
- Vector3 v2 = { x - w/2, h2, z + h/2 };
- Vector3 v3 = { x + w/2, h2, z + h/2 };
- Vector3 v4 = { x + w/2, h2, z - h/2 };
- Vector3 v5 = { x + w/2, 0, z - h/2 };
- Vector3 v6 = { x - w/2, 0, z - h/2 };
- Vector3 v7 = { x - w/2, 0, z + h/2 };
- Vector3 v8 = { x + w/2, 0, z + h/2 };
+ Vector3 v1 = { w*(x - 0.5f), h2, h*(z - 0.5f) };
+ Vector3 v2 = { w*(x - 0.5f), h2, h*(z + 0.5f) };
+ Vector3 v3 = { w*(x + 0.5f), h2, h*(z + 0.5f) };
+ Vector3 v4 = { w*(x + 0.5f), h2, h*(z - 0.5f) };
+ Vector3 v5 = { w*(x + 0.5f), 0, h*(z - 0.5f) };
+ Vector3 v6 = { w*(x - 0.5f), 0, h*(z - 0.5f) };
+ Vector3 v7 = { w*(x - 0.5f), 0, h*(z + 0.5f) };
+ Vector3 v8 = { w*(x + 0.5f), 0, h*(z + 0.5f) };
// We check pixel color to be WHITE, we will full cubes
if ((cubicmapPixels[z*cubicmap.width + x].r == 255) &&
@@ -1262,9 +1270,9 @@ static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize)
free(mapVertices);
free(mapNormals);
free(mapTexcoords);
-
+
free(cubicmapPixels); // Free image pixel data
-
+
return mesh;
}
@@ -1273,7 +1281,7 @@ void DrawModel(Model model, Vector3 position, float scale, Color tint)
{
Vector3 vScale = { scale, scale, scale };
Vector3 rotationAxis = { 0.0f, 0.0f, 0.0f };
-
+
DrawModelEx(model, position, rotationAxis, 0.0f, vScale, tint);
}
@@ -1285,13 +1293,13 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
Matrix matRotation = MatrixRotate(rotationAxis, rotationAngle*DEG2RAD);
Matrix matScale = MatrixScale(scale.x, scale.y, scale.z);
Matrix matTranslation = MatrixTranslate(position.x, position.y, position.z);
-
+
// Combine model transformation matrix (model.transform) with matrix generated by function parameters (matTransform)
//Matrix matModel = MatrixMultiply(model.transform, matTransform); // Transform to world-space coordinates
-
+
model.transform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color?
-
+
rlglDrawMesh(model.mesh, model.material, model.transform);
}
@@ -1299,9 +1307,9 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
{
rlEnableWireMode();
-
+
DrawModel(model, position, scale, tint);
-
+
rlDisableWireMode();
}
@@ -1309,9 +1317,9 @@ void DrawModelWires(Model model, Vector3 position, float scale, Color tint)
void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint)
{
rlEnableWireMode();
-
+
DrawModelEx(model, position, rotationAxis, rotationAngle, scale, tint);
-
+
rlDisableWireMode();
}
@@ -1319,7 +1327,7 @@ void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis, float
void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint)
{
Rectangle sourceRec = { 0, 0, texture.width, texture.height };
-
+
DrawBillboardRec(camera, texture, sourceRec, center, size, tint);
}
@@ -1334,7 +1342,7 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
Vector3 right = { viewMatrix.m0, viewMatrix.m4, viewMatrix.m8 };
//Vector3 up = { viewMatrix.m1, viewMatrix.m5, viewMatrix.m9 };
-
+
// NOTE: Billboard locked on axis-Y
Vector3 up = { 0.0f, 1.0f, 0.0f };
/*
@@ -1361,19 +1369,19 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
// Bottom-left corner for texture and quad
- rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
+ rlTexCoord2f((float)sourceRec.x/texture.width, (float)sourceRec.y/texture.height);
rlVertex3f(a.x, a.y, a.z);
// Top-left corner for texture and quad
- rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
rlVertex3f(d.x, d.y, d.z);
// Top-right corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
rlVertex3f(c.x, c.y, c.z);
// Bottom-right corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
+ rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height);
rlVertex3f(b.x, b.y, b.z);
rlEnd();
@@ -1384,13 +1392,13 @@ void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vec
void DrawBoundingBox(BoundingBox box, Color color)
{
Vector3 size;
-
+
size.x = fabsf(box.max.x - box.min.x);
size.y = fabsf(box.max.y - box.min.y);
size.z = fabsf(box.max.z - box.min.z);
-
+
Vector3 center = { box.min.x + size.x/2.0f, box.min.y + size.y/2.0f, box.min.z + size.z/2.0f };
-
+
DrawCubeWires(center, size.x, size.y, size.z, color);
}
@@ -1451,14 +1459,14 @@ bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radius
bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius)
{
bool collision = false;
-
+
Vector3 raySpherePos = VectorSubtract(spherePosition, ray.position);
float distance = VectorLength(raySpherePos);
float vector = VectorDotProduct(raySpherePos, ray.direction);
float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
-
+
if (d >= 0.0f) collision = true;
-
+
return collision;
}
@@ -1466,29 +1474,29 @@ bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius
bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint)
{
bool collision = false;
-
+
Vector3 raySpherePos = VectorSubtract(spherePosition, ray.position);
float distance = VectorLength(raySpherePos);
float vector = VectorDotProduct(raySpherePos, ray.direction);
float d = sphereRadius*sphereRadius - (distance*distance - vector*vector);
-
+
if (d >= 0.0f) collision = true;
-
+
// Calculate collision point
Vector3 offset = ray.direction;
float collisionDistance = 0;
-
+
// Check if ray origin is inside the sphere to calculate the correct collision point
if (distance < sphereRadius) collisionDistance = vector + sqrt(d);
else collisionDistance = vector - sqrt(d);
-
+
VectorScale(&offset, collisionDistance);
Vector3 cPoint = VectorAdd(ray.position, offset);
-
+
collisionPoint->x = cPoint.x;
collisionPoint->y = cPoint.y;
collisionPoint->z = cPoint.z;
-
+
return collision;
}
@@ -1496,7 +1504,7 @@ bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadi
bool CheckCollisionRayBox(Ray ray, BoundingBox box)
{
bool collision = false;
-
+
float t[8];
t[0] = (box.min.x - ray.position.x)/ray.direction.x;
t[1] = (box.max.x - ray.position.x)/ray.direction.x;
@@ -1506,9 +1514,9 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box)
t[5] = (box.max.z - ray.position.z)/ray.direction.z;
t[6] = fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]));
t[7] = fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]));
-
+
collision = !(t[7] < 0 || t[6] > t[7]);
-
+
return collision;
}
@@ -1524,270 +1532,20 @@ BoundingBox CalculateBoundingBox(Mesh mesh)
{
minVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
maxVertex = (Vector3){ mesh.vertices[0], mesh.vertices[1], mesh.vertices[2] };
-
+
for (int i = 1; i < mesh.vertexCount; i++)
{
minVertex = VectorMin(minVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
maxVertex = VectorMax(maxVertex, (Vector3){ mesh.vertices[i*3], mesh.vertices[i*3 + 1], mesh.vertices[i*3 + 2] });
}
}
-
+
// Create the bounding box
BoundingBox box;
box.min = minVertex;
box.max = maxVertex;
-
- return box;
-}
-
-// Detect and resolve cubicmap collisions
-// NOTE: player position (or camera) is modified inside this function
-// TODO: This functions needs to be completely reviewed!
-Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius)
-{
- #define CUBIC_MAP_HALF_BLOCK_SIZE 0.5
-
- Color *cubicmapPixels = GetImageData(cubicmap);
-
- // Detect the cell where the player is located
- Vector3 impactDirection = { 0.0f, 0.0f, 0.0f };
-
- int locationCellX = 0;
- int locationCellY = 0;
-
- locationCellX = floor(playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE);
- locationCellY = floor(playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE);
-
- if ((locationCellX >= 0) && (locationCellY >= 0) && (locationCellX < cubicmap.width) && (locationCellY < cubicmap.height))
- {
- // Multiple Axis --------------------------------------------------------------------------------------------
-
- // Axis x-, y-
- if ((locationCellX > 0) && (locationCellY > 0))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) &&
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
- {
- playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
-
- // Axis x-, y+
- if ((locationCellX > 0) && (locationCellY < cubicmap.height - 1))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0) &&
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
- {
- playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
- // Axis x+, y-
- if ((locationCellX < cubicmap.width - 1) && (locationCellY > 0))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) &&
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
- {
- playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
-
- // Axis x+, y+
- if ((locationCellX < cubicmap.width - 1) && (locationCellY < cubicmap.height - 1))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0) &&
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
- {
- playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
-
- // Single Axis ---------------------------------------------------------------------------------------------------
-
- // Axis x-
- if (locationCellX > 0)
- {
- if (cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r != 0)
- {
- if ((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius)
- {
- playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 1.0f, 0.0f, 0.0f };
- }
- }
- }
- // Axis x+
- if (locationCellX < cubicmap.width - 1)
- {
- if (cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r != 0)
- {
- if ((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius)
- {
- playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 1.0f, 0.0f, 0.0f };
- }
- }
- }
- // Axis y-
- if (locationCellY > 0)
- {
- if (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r != 0)
- {
- if ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius)
- {
- playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 0.0f, 0.0f, 1.0f };
- }
- }
- }
- // Axis y+
- if (locationCellY < cubicmap.height - 1)
- {
- if (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r != 0)
- {
- if ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius)
- {
- playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- impactDirection = (Vector3){ 0.0f, 0.0f, 1.0f };
- }
- }
- }
-
- // Diagonals -------------------------------------------------------------------------------------------------------
-
- // Axis x-, y-
- if ((locationCellX > 0) && (locationCellY > 0))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r == 0) &&
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r == 0) &&
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX - 1)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- else playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
-
- // Return ricochet
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3))
- {
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
- }
-
- // Axis x-, y+
- if ((locationCellX > 0) && (locationCellY < cubicmap.height - 1))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX - 1)].r == 0) &&
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) &&
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX - 1)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) > (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX + mapPosition.x - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- else playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
-
- // Return ricochet
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX < radius / 3) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3))
- {
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
- }
-
- // Axis x+, y-
- if ((locationCellX < cubicmap.width - 1) && (locationCellY > 0))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) &&
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX)].r == 0) &&
- (cubicmapPixels[(locationCellY - 1)*cubicmap.width + (locationCellX + 1)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < (1 - ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY))) playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- else playerPosition->z = locationCellY + mapPosition.z - (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
-
- // Return ricochet
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY < radius / 3))
- {
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
- }
-
- // Axis x+, y+
- if ((locationCellX < cubicmap.width - 1) && (locationCellY < cubicmap.height - 1))
- {
- if ((cubicmapPixels[locationCellY*cubicmap.width + (locationCellX + 1)].r == 0) &&
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX)].r == 0) &&
- (cubicmapPixels[(locationCellY + 1)*cubicmap.width + (locationCellX + 1)].r != 0))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius))
- {
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX) < ((playerPosition->z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY)) playerPosition->x = locationCellX + mapPosition.x + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
- else playerPosition->z = locationCellY + mapPosition.z + (CUBIC_MAP_HALF_BLOCK_SIZE - radius);
-
- // Return ricochet
- if (((playerPosition->x - mapPosition.x + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellX > 1 - radius / 3) &&
- ((playerPosition->z - mapPosition.z + CUBIC_MAP_HALF_BLOCK_SIZE) - locationCellY > 1 - radius / 3))
- {
- impactDirection = (Vector3){ 1.0f, 0.0f, 1.0f };
- }
- }
- }
- }
- }
-
- // Floor collision
- if (playerPosition->y <= radius)
- {
- playerPosition->y = radius + 0.01f;
- impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z};
- }
- // Roof collision
- else if (playerPosition->y >= (1.5f - radius))
- {
- playerPosition->y = (1.5f - radius) - 0.01f;
- impactDirection = (Vector3) { impactDirection.x, 1, impactDirection.z};
- }
-
- free(cubicmapPixels);
-
- return impactDirection;
+ return box;
}
//----------------------------------------------------------------------------------
@@ -1898,23 +1656,21 @@ static Mesh LoadOBJ(const char *fileName)
if (dataType == 't') // Read texCoord
{
- float useless = 0;
-
- fscanf(objFile, "%f %f %f", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y, &useless);
+ fscanf(objFile, "%f %f%*[^\n]s\n", &midTexCoords[countTexCoords].x, &midTexCoords[countTexCoords].y);
countTexCoords++;
fscanf(objFile, "%c", &dataType);
}
else if (dataType == 'n') // Read normals
{
- fscanf(objFile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z );
+ fscanf(objFile, "%f %f %f", &midNormals[countNormals].x, &midNormals[countNormals].y, &midNormals[countNormals].z);
countNormals++;
fscanf(objFile, "%c", &dataType);
}
else // Read vertex
{
- fscanf(objFile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z );
+ fscanf(objFile, "%f %f %f", &midVertices[countVertex].x, &midVertices[countVertex].y, &midVertices[countVertex].z);
countVertex++;
fscanf(objFile, "%c", &dataType);
@@ -1959,6 +1715,7 @@ static Mesh LoadOBJ(const char *fileName)
if ((numNormals == 0) && (numTexCoords == 0)) fscanf(objFile, "%i %i %i", &vNum[0], &vNum[1], &vNum[2]);
else if (numNormals == 0) fscanf(objFile, "%i/%i %i/%i %i/%i", &vNum[0], &vtNum[0], &vNum[1], &vtNum[1], &vNum[2], &vtNum[2]);
+ else if (numTexCoords == 0) fscanf(objFile, "%i//%i %i//%i %i//%i", &vNum[0], &vnNum[0], &vNum[1], &vnNum[1], &vNum[2], &vnNum[2]);
else fscanf(objFile, "%i/%i/%i %i/%i/%i %i/%i/%i", &vNum[0], &vtNum[0], &vnNum[0], &vNum[1], &vtNum[1], &vnNum[1], &vNum[2], &vtNum[2], &vnNum[2]);
mesh.vertices[vCounter] = midVertices[vNum[0]-1].x;
@@ -2049,9 +1806,9 @@ static Mesh LoadOBJ(const char *fileName)
static Material LoadMTL(const char *fileName)
{
#define MAX_BUFFER_SIZE 128
-
+
Material material = { 0 }; // LoadDefaultMaterial();
-
+
char buffer[MAX_BUFFER_SIZE];
Vector3 color = { 1.0f, 1.0f, 1.0f };
char *mapFileName = NULL;
@@ -2069,14 +1826,14 @@ static Material LoadMTL(const char *fileName)
while (!feof(mtlFile))
{
fgets(buffer, MAX_BUFFER_SIZE, mtlFile);
-
+
switch (buffer[0])
{
case 'n': // newmtl string Material name. Begins a new material description.
{
// TODO: Support multiple materials in a single .mtl
sscanf(buffer, "newmtl %s", mapFileName);
-
+
TraceLog(INFO, "[%s] Loading material...", mapFileName);
}
case 'i': // illum int Illumination model
@@ -2123,7 +1880,7 @@ static Material LoadMTL(const char *fileName)
{
int shininess = 0;
sscanf(buffer, "Ns %i", &shininess);
-
+
material.glossiness = (float)shininess;
}
else if (buffer[1] == 'i') // Ni int Refraction index.
@@ -2192,7 +1949,7 @@ static Material LoadMTL(const char *fileName)
float ialpha = 0.0f;
sscanf(buffer, "Tr %f", &ialpha);
material.colDiffuse.a = (unsigned char)((1.0f - ialpha)*255);
-
+
} break;
case 'r': // refl string Reflection texture map
default: break;
@@ -2203,6 +1960,6 @@ static Material LoadMTL(const char *fileName)
// NOTE: At this point we have all material data
TraceLog(INFO, "[%s] Material loaded successfully", fileName);
-
+
return material;
}
diff --git a/src/raygui.h b/src/raygui.h
deleted file mode 100644
index 42cf264b..00000000
--- a/src/raygui.h
+++ /dev/null
@@ -1,1499 +0,0 @@
-/*******************************************************************************************
-*
-* raygui 1.0 - IMGUI (Immedite Mode GUI) library for raylib (https://github.com/raysan5/raylib)
-*
-* raygui is a library for creating simple IMGUI interfaces using raylib.
-* It provides a set of basic components:
-*
-* - Label
-* - Button
-* - ToggleButton
-* - ToggleGroup
-* - ComboBox
-* - CheckBox
-* - Slider
-* - SliderBar
-* - ProgressBar
-* - Spinner
-* - TextBox
-*
-* It also provides a set of functions for styling the components based on its properties (size, color).
-*
-* CONFIGURATION:
-*
-* #define RAYGUI_IMPLEMENTATION
-* Generates the implementation of the library into the included file.
-* If not defined, the library is in header only mode and can be included in other headers
-* or source files without problems. But only ONE file should hold the implementation.
-*
-* #define RAYGUI_STATIC (defined by default)
-* The generated implementation will stay private inside implementation file and all
-* internal symbols and functions will only be visible inside that file.
-*
-* #define RAYGUI_STANDALONE
-* Avoid raylib.h header inclusion in this file. Data types defined on raylib are defined
-* internally in the library and input management and drawing functions must be provided by
-* the user (check library implementation for further details).
-*
-* #define RAYGUI_MALLOC()
-* #define RAYGUI_FREE()
-* You can define your own malloc/free implementation replacing stdlib.h malloc()/free() functions.
-* Otherwise it will include stdlib.h and use the C standard library malloc()/free() function.
-*
-* LIMITATIONS:
-*
-* // TODO.
-*
-* VERSIONS:
-*
-* 1.0 (07-Jun-2016) Converted to header-only by Ramon Santamaria.
-* 0.9 (07-Mar-2016) Reviewed and tested by Albert Martos, Ian Eito, Sergio Martinez and Ramon Santamaria.
-* 0.8 (27-Aug-2015) Initial release. Implemented by Kevin Gato, Daniel Nicolás and Ramon Santamaria.
-*
-* CONTRIBUTORS:
-* Ramon Santamaria: Functions design and naming conventions.
-* Kevin Gato: Initial implementation of basic components.
-* Daniel Nicolas: Initial implementation of basic components.
-* Albert Martos: Review and testing of library.
-* Ian Eito: Review and testing of the library.
-* Sergio Martinez: Review and testing of the library.
-*
-* LICENSE: zlib/libpng
-*
-* Copyright (c) 2015-2016 emegeme (@emegemegames)
-*
-* 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 RAYGUI_H
-#define RAYGUI_H
-
-#if !defined(RAYGUI_STANDALONE)
- #include "raylib.h"
-#endif
-
-#define RAYGUI_STATIC
-#ifdef RAYGUI_STATIC
- #define RAYGUIDEF static // Functions just visible to module including this file
-#else
- #ifdef __cplusplus
- #define RAYGUIDEF extern "C" // Functions visible from other files (no name mangling of functions in C++)
- #else
- #define RAYGUIDEF extern // Functions visible from other files
- #endif
-#endif
-
-//----------------------------------------------------------------------------------
-// Defines and Macros
-//----------------------------------------------------------------------------------
-#define NUM_PROPERTIES 98
-
-//----------------------------------------------------------------------------------
-// Types and Structures Definition
-// NOTE: Some types are required for RAYGUI_STANDALONE usage
-//----------------------------------------------------------------------------------
-#if defined(RAYGUI_STANDALONE)
- #ifndef __cplusplus
- // Boolean type
- #ifndef true
- typedef enum { false, true } bool;
- #endif
- #endif
-
- // Vector2 type
- typedef struct Vector2 {
- float x;
- float y;
- } Vector2;
-
- // 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;
-#endif
-
-// Gui properties enumeration
-typedef enum GuiProperty {
- GLOBAL_BASE_COLOR = 0,
- GLOBAL_BORDER_COLOR,
- GLOBAL_TEXT_COLOR,
- GLOBAL_TEXT_FONTSIZE,
- GLOBAL_BORDER_WIDTH,
- BACKGROUND_COLOR,
- LABEL_BORDER_WIDTH,
- LABEL_TEXT_COLOR,
- LABEL_TEXT_PADDING,
- BUTTON_BORDER_WIDTH,
- BUTTON_TEXT_PADDING,
- BUTTON_DEFAULT_BORDER_COLOR,
- BUTTON_DEFAULT_INSIDE_COLOR,
- BUTTON_DEFAULT_TEXT_COLOR,
- BUTTON_HOVER_BORDER_COLOR,
- BUTTON_HOVER_INSIDE_COLOR,
- BUTTON_HOVER_TEXT_COLOR,
- BUTTON_PRESSED_BORDER_COLOR,
- BUTTON_PRESSED_INSIDE_COLOR,
- BUTTON_PRESSED_TEXT_COLOR,
- TOGGLE_TEXT_PADDING,
- TOGGLE_BORDER_WIDTH,
- TOGGLE_DEFAULT_BORDER_COLOR,
- TOGGLE_DEFAULT_INSIDE_COLOR,
- TOGGLE_DEFAULT_TEXT_COLOR,
- TOGGLE_HOVER_BORDER_COLOR,
- TOGGLE_HOVER_INSIDE_COLOR,
- TOGGLE_HOVER_TEXT_COLOR,
- TOGGLE_PRESSED_BORDER_COLOR,
- TOGGLE_PRESSED_INSIDE_COLOR,
- TOGGLE_PRESSED_TEXT_COLOR,
- TOGGLE_ACTIVE_BORDER_COLOR,
- TOGGLE_ACTIVE_INSIDE_COLOR,
- TOGGLE_ACTIVE_TEXT_COLOR,
- TOGGLEGROUP_PADDING,
- SLIDER_BORDER_WIDTH,
- SLIDER_BUTTON_BORDER_WIDTH,
- SLIDER_BORDER_COLOR,
- SLIDER_INSIDE_COLOR,
- SLIDER_DEFAULT_COLOR,
- SLIDER_HOVER_COLOR,
- SLIDER_ACTIVE_COLOR,
- SLIDERBAR_BORDER_COLOR,
- SLIDERBAR_INSIDE_COLOR,
- SLIDERBAR_DEFAULT_COLOR,
- SLIDERBAR_HOVER_COLOR,
- SLIDERBAR_ACTIVE_COLOR,
- SLIDERBAR_ZERO_LINE_COLOR,
- PROGRESSBAR_BORDER_COLOR,
- PROGRESSBAR_INSIDE_COLOR,
- PROGRESSBAR_PROGRESS_COLOR,
- PROGRESSBAR_BORDER_WIDTH,
- SPINNER_LABEL_BORDER_COLOR,
- SPINNER_LABEL_INSIDE_COLOR,
- SPINNER_DEFAULT_BUTTON_BORDER_COLOR,
- SPINNER_DEFAULT_BUTTON_INSIDE_COLOR,
- SPINNER_DEFAULT_SYMBOL_COLOR,
- SPINNER_DEFAULT_TEXT_COLOR,
- SPINNER_HOVER_BUTTON_BORDER_COLOR,
- SPINNER_HOVER_BUTTON_INSIDE_COLOR,
- SPINNER_HOVER_SYMBOL_COLOR,
- SPINNER_HOVER_TEXT_COLOR,
- SPINNER_PRESSED_BUTTON_BORDER_COLOR,
- SPINNER_PRESSED_BUTTON_INSIDE_COLOR,
- SPINNER_PRESSED_SYMBOL_COLOR,
- SPINNER_PRESSED_TEXT_COLOR,
- COMBOBOX_PADDING,
- COMBOBOX_BUTTON_WIDTH,
- COMBOBOX_BUTTON_HEIGHT,
- COMBOBOX_BORDER_WIDTH,
- COMBOBOX_DEFAULT_BORDER_COLOR,
- COMBOBOX_DEFAULT_INSIDE_COLOR,
- COMBOBOX_DEFAULT_TEXT_COLOR,
- COMBOBOX_DEFAULT_LIST_TEXT_COLOR,
- COMBOBOX_HOVER_BORDER_COLOR,
- COMBOBOX_HOVER_INSIDE_COLOR,
- COMBOBOX_HOVER_TEXT_COLOR,
- COMBOBOX_HOVER_LIST_TEXT_COLOR,
- COMBOBOX_PRESSED_BORDER_COLOR,
- COMBOBOX_PRESSED_INSIDE_COLOR,
- COMBOBOX_PRESSED_TEXT_COLOR,
- COMBOBOX_PRESSED_LIST_BORDER_COLOR,
- COMBOBOX_PRESSED_LIST_INSIDE_COLOR,
- COMBOBOX_PRESSED_LIST_TEXT_COLOR,
- CHECKBOX_DEFAULT_BORDER_COLOR,
- CHECKBOX_DEFAULT_INSIDE_COLOR,
- CHECKBOX_HOVER_BORDER_COLOR,
- CHECKBOX_HOVER_INSIDE_COLOR,
- CHECKBOX_CLICK_BORDER_COLOR,
- CHECKBOX_CLICK_INSIDE_COLOR,
- CHECKBOX_STATUS_ACTIVE_COLOR,
- CHECKBOX_INSIDE_WIDTH,
- TEXTBOX_BORDER_WIDTH,
- TEXTBOX_BORDER_COLOR,
- TEXTBOX_INSIDE_COLOR,
- TEXTBOX_TEXT_COLOR,
- TEXTBOX_LINE_COLOR,
- TEXTBOX_TEXT_FONTSIZE
-} GuiProperty;
-
-//----------------------------------------------------------------------------------
-// Global Variables Definition
-//----------------------------------------------------------------------------------
-// ...
-
-//----------------------------------------------------------------------------------
-// Module Functions Declaration
-//----------------------------------------------------------------------------------
-RAYGUIDEF void GuiLabel(Rectangle bounds, const char *text); // Label element, show text
-RAYGUIDEF void GuiLabelEx(Rectangle bounds, const char *text, Color textColor, Color border, Color inner); // Label element extended, configurable colors
-RAYGUIDEF bool GuiButton(Rectangle bounds, const char *text); // Button element, returns true when clicked
-RAYGUIDEF bool GuiToggleButton(Rectangle bounds, const char *text, bool toggle); // Toggle Button element, returns true when active
-RAYGUIDEF int GuiToggleGroup(Rectangle bounds, int toggleNum, char **toggleText, int toggleActive); // Toggle Group element, returns toggled button index
-RAYGUIDEF int GuiComboBox(Rectangle bounds, int comboNum, char **comboText, int comboActive); // Combo Box element, returns selected item index
-RAYGUIDEF bool GuiCheckBox(Rectangle bounds, const char *text, bool checked); // Check Box element, returns true when active
-RAYGUIDEF float GuiSlider(Rectangle bounds, float value, float minValue, float maxValue); // Slider element, returns selected value
-RAYGUIDEF float GuiSliderBar(Rectangle bounds, float value, float minValue, float maxValue); // Slider Bar element, returns selected value
-RAYGUIDEF void GuiProgressBar(Rectangle bounds, float value); // Progress Bar element, shows current progress value
-RAYGUIDEF int GuiSpinner(Rectangle bounds, int value, int minValue, int maxValue); // Spinner element, returns selected value
-RAYGUIDEF char *GuiTextBox(Rectangle bounds, char *text); // Text Box element, returns input text
-
-RAYGUIDEF void SaveGuiStyle(const char *fileName); // Save GUI style file
-RAYGUIDEF void LoadGuiStyle(const char *fileName); // Load GUI style file
-
-RAYGUIDEF void SetStyleProperty(int guiProperty, int value); // Set one style property
-RAYGUIDEF int GetStyleProperty(int guiProperty); // Get one style property
-
-#endif // RAYGUI_H
-
-
-/***********************************************************************************
-*
-* RAYGUI IMPLEMENTATION
-*
-************************************************************************************/
-
-#if defined(RAYGUI_IMPLEMENTATION)
-
-#include <stdio.h> // Required for: FILE, fopen(), fclose(), fprintf(), feof(), fscanf()
- // NOTE: Those functions are only used in SaveGuiStyle() and LoadGuiStyle()
-
-// Check if custom malloc/free functions defined, if not, using standard ones
-#if !defined(RAYGUI_MALLOC)
- #include <stdlib.h> // Required for: malloc(), free() [Used only on LoadGuiStyle()]
-
- #define RAYGUI_MALLOC(size) malloc(size)
- #define RAYGUI_FREE(ptr) free(ptr)
-#endif
-
-#include <string.h> // Required for: strcmp() [Used only on LoadGuiStyle()]
-#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
-
-//----------------------------------------------------------------------------------
-// Defines and Macros
-//----------------------------------------------------------------------------------
-#if defined(RAYGUI_STANDALONE)
- #define KEY_LEFT 263
- #define KEY_RIGHT 262
- #define MOUSE_LEFT_BUTTON 0
-#endif
-
-//----------------------------------------------------------------------------------
-// Types and Structures Definition
-//----------------------------------------------------------------------------------
-
-// GUI elements states
-typedef enum { BUTTON_DEFAULT, BUTTON_HOVER, BUTTON_PRESSED, BUTTON_CLICKED } ButtonState;
-typedef enum { TOGGLE_UNACTIVE, TOGGLE_HOVER, TOGGLE_PRESSED, TOGGLE_ACTIVE } ToggleState;
-typedef enum { COMBOBOX_UNACTIVE, COMBOBOX_HOVER, COMBOBOX_PRESSED, COMBOBOX_ACTIVE } ComboBoxState;
-typedef enum { SPINNER_DEFAULT, SPINNER_HOVER, SPINNER_PRESSED } SpinnerState;
-typedef enum { CHECKBOX_STATUS, CHECKBOX_HOVER, CHECKBOX_PRESSED } CheckBoxState;
-typedef enum { SLIDER_DEFAULT, SLIDER_HOVER, SLIDER_ACTIVE } SliderState;
-
-//----------------------------------------------------------------------------------
-// Global Variables Definition
-//----------------------------------------------------------------------------------
-
-// Current GUI style (default light)
-static int style[NUM_PROPERTIES] = {
- 0xf5f5f5ff, // GLOBAL_BASE_COLOR,
- 0xf5f5f5ff, // GLOBAL_BORDER_COLOR,
- 0xf5f5f5ff, // GLOBAL_TEXT_COLOR,
- 10, // GLOBAL_TEXT_FONTSIZE
- 1, // GLOBAL_BORDER_WIDTH
- 0xf5f5f5ff, // BACKGROUND_COLOR
- 1, // LABEL_BORDER_WIDTH
- 0x4d4d4dff, // LABEL_TEXT_COLOR
- 20, // LABEL_TEXT_PADDING
- 2, // BUTTON_BORDER_WIDTH
- 20, // BUTTON_TEXT_PADDING
- 0x828282ff, // BUTTON_DEFAULT_BORDER_COLOR
- 0xc8c8c8ff, // BUTTON_DEFAULT_INSIDE_COLOR
- 0x4d4d4dff, // BUTTON_DEFAULT_TEXT_COLOR
- 0xc8c8c8ff, // BUTTON_HOVER_BORDER_COLOR
- 0xffffffff, // BUTTON_HOVER_INSIDE_COLOR
- 0x353535ff, // BUTTON_HOVER_TEXT_COLOR
- 0x7bb0d6ff, // BUTTON_PRESSED_BORDER_COLOR
- 0xbcecffff, // BUTTON_PRESSED_INSIDE_COLOR
- 0x5f9aa7ff, // BUTTON_PRESSED_TEXT_COLOR
- 20, // TOGGLE_TEXT_PADDING
- 1, // TOGGLE_BORDER_WIDTH
- 0x828282ff, // TOGGLE_DEFAULT_BORDER_COLOR
- 0xc8c8c8ff, // TOGGLE_DEFAULT_INSIDE_COLOR
- 0x828282ff, // TOGGLE_DEFAULT_TEXT_COLOR
- 0xc8c8c8ff, // TOGGLE_HOVER_BORDER_COLOR
- 0xffffffff, // TOGGLE_HOVER_INSIDE_COLOR
- 0x828282ff, // TOGGLE_HOVER_TEXT_COLOR
- 0xbdd7eaff, // TOGGLE_PRESSED_BORDER_COLOR
- 0xddf5ffff, // TOGGLE_PRESSED_INSIDE_COLOR
- 0xafccd3ff, // TOGGLE_PRESSED_TEXT_COLOR
- 0x7bb0d6ff, // TOGGLE_ACTIVE_BORDER_COLOR
- 0xbcecffff, // TOGGLE_ACTIVE_INSIDE_COLOR
- 0x5f9aa7ff, // TOGGLE_ACTIVE_TEXT_COLOR
- 3, // TOGGLEGROUP_PADDING
- 1, // SLIDER_BORDER_WIDTH
- 1, // SLIDER_BUTTON_BORDER_WIDTH
- 0x828282ff, // SLIDER_BORDER_COLOR
- 0xc8c8c8ff, // SLIDER_INSIDE_COLOR
- 0xbcecffff, // SLIDER_DEFAULT_COLOR
- 0xffffffff, // SLIDER_HOVER_COLOR
- 0xddf5ffff, // SLIDER_ACTIVE_COLOR
- 0x828282ff, // SLIDERBAR_BORDER_COLOR
- 0xc8c8c8ff, // SLIDERBAR_INSIDE_COLOR
- 0xbcecffff, // SLIDERBAR_DEFAULT_COLOR
- 0xffffffff, // SLIDERBAR_HOVER_COLOR
- 0xddf5ffff, // SLIDERBAR_ACTIVE_COLOR
- 0x828282ff, // SLIDERBAR_ZERO_LINE_COLOR
- 0x828282ff, // PROGRESSBAR_BORDER_COLOR
- 0xc8c8c8ff, // PROGRESSBAR_INSIDE_COLOR
- 0xbcecffff, // PROGRESSBAR_PROGRESS_COLOR
- 2, // PROGRESSBAR_BORDER_WIDTH
- 0x828282ff, // SPINNER_LABEL_BORDER_COLOR
- 0xc8c8c8ff, // SPINNER_LABEL_INSIDE_COLOR
- 0x828282ff, // SPINNER_DEFAULT_BUTTON_BORDER_COLOR
- 0xc8c8c8ff, // SPINNER_DEFAULT_BUTTON_INSIDE_COLOR
- 0x000000ff, // SPINNER_DEFAULT_SYMBOL_COLOR
- 0x000000ff, // SPINNER_DEFAULT_TEXT_COLOR
- 0xc8c8c8ff, // SPINNER_HOVER_BUTTON_BORDER_COLOR
- 0xffffffff, // SPINNER_HOVER_BUTTON_INSIDE_COLOR
- 0x000000ff, // SPINNER_HOVER_SYMBOL_COLOR
- 0x000000ff, // SPINNER_HOVER_TEXT_COLOR
- 0x7bb0d6ff, // SPINNER_PRESSED_BUTTON_BORDER_COLOR
- 0xbcecffff, // SPINNER_PRESSED_BUTTON_INSIDE_COLOR
- 0x5f9aa7ff, // SPINNER_PRESSED_SYMBOL_COLOR
- 0x000000ff, // SPINNER_PRESSED_TEXT_COLOR
- 1, // COMBOBOX_PADDING
- 30, // COMBOBOX_BUTTON_WIDTH
- 20, // COMBOBOX_BUTTON_HEIGHT
- 1, // COMBOBOX_BORDER_WIDTH
- 0x828282ff, // COMBOBOX_DEFAULT_BORDER_COLOR
- 0xc8c8c8ff, // COMBOBOX_DEFAULT_INSIDE_COLOR
- 0x828282ff, // COMBOBOX_DEFAULT_TEXT_COLOR
- 0x828282ff, // COMBOBOX_DEFAULT_LIST_TEXT_COLOR
- 0xc8c8c8ff, // COMBOBOX_HOVER_BORDER_COLOR
- 0xffffffff, // COMBOBOX_HOVER_INSIDE_COLOR
- 0x828282ff, // COMBOBOX_HOVER_TEXT_COLOR
- 0x828282ff, // COMBOBOX_HOVER_LIST_TEXT_COLOR
- 0x7bb0d6ff, // COMBOBOX_PRESSED_BORDER_COLOR
- 0xbcecffff, // COMBOBOX_PRESSED_INSIDE_COLOR
- 0x5f9aa7ff, // COMBOBOX_PRESSED_TEXT_COLOR
- 0x0078acff, // COMBOBOX_PRESSED_LIST_BORDER_COLOR
- 0x66e7ffff, // COMBOBOX_PRESSED_LIST_INSIDE_COLOR
- 0x0078acff, // COMBOBOX_PRESSED_LIST_TEXT_COLOR
- 0x828282ff, // CHECKBOX_DEFAULT_BORDER_COLOR
- 0xffffffff, // CHECKBOX_DEFAULT_INSIDE_COLOR
- 0xc8c8c8ff, // CHECKBOX_HOVER_BORDER_COLOR
- 0xffffffff, // CHECKBOX_HOVER_INSIDE_COLOR
- 0x66e7ffff, // CHECKBOX_CLICK_BORDER_COLOR
- 0xddf5ffff, // CHECKBOX_CLICK_INSIDE_COLOR
- 0x7bb0d6ff, // CHECKBOX_STATUS_ACTIVE_COLOR
- 4, // CHECKBOX_INSIDE_WIDTH
- 1, // TEXTBOX_BORDER_WIDTH
- 0x828282ff, // TEXTBOX_BORDER_COLOR
- 0xf5f5f5ff, // TEXTBOX_INSIDE_COLOR
- 0x000000ff, // TEXTBOX_TEXT_COLOR
- 0x000000ff, // TEXTBOX_LINE_COLOR
- 10 // TEXTBOX_TEXT_FONTSIZE
-};
-
-// GUI property names (to read/write style text files)
-static const char *guiPropertyName[] = {
- "GLOBAL_BASE_COLOR",
- "GLOBAL_BORDER_COLOR",
- "GLOBAL_TEXT_COLOR",
- "GLOBAL_TEXT_FONTSIZE",
- "GLOBAL_BORDER_WIDTH",
- "BACKGROUND_COLOR",
- "LABEL_BORDER_WIDTH",
- "LABEL_TEXT_COLOR",
- "LABEL_TEXT_PADDING",
- "BUTTON_BORDER_WIDTH",
- "BUTTON_TEXT_PADDING",
- "BUTTON_DEFAULT_BORDER_COLOR",
- "BUTTON_DEFAULT_INSIDE_COLOR",
- "BUTTON_DEFAULT_TEXT_COLOR",
- "BUTTON_HOVER_BORDER_COLOR",
- "BUTTON_HOVER_INSIDE_COLOR",
- "BUTTON_HOVER_TEXT_COLOR",
- "BUTTON_PRESSED_BORDER_COLOR",
- "BUTTON_PRESSED_INSIDE_COLOR",
- "BUTTON_PRESSED_TEXT_COLOR",
- "TOGGLE_TEXT_PADDING",
- "TOGGLE_BORDER_WIDTH",
- "TOGGLE_DEFAULT_BORDER_COLOR",
- "TOGGLE_DEFAULT_INSIDE_COLOR",
- "TOGGLE_DEFAULT_TEXT_COLOR",
- "TOGGLE_HOVER_BORDER_COLOR",
- "TOGGLE_HOVER_INSIDE_COLOR",
- "TOGGLE_HOVER_TEXT_COLOR",
- "TOGGLE_PRESSED_BORDER_COLOR",
- "TOGGLE_PRESSED_INSIDE_COLOR",
- "TOGGLE_PRESSED_TEXT_COLOR",
- "TOGGLE_ACTIVE_BORDER_COLOR",
- "TOGGLE_ACTIVE_INSIDE_COLOR",
- "TOGGLE_ACTIVE_TEXT_COLOR",
- "TOGGLEGROUP_PADDING",
- "SLIDER_BORDER_WIDTH",
- "SLIDER_BUTTON_BORDER_WIDTH",
- "SLIDER_BORDER_COLOR",
- "SLIDER_INSIDE_COLOR",
- "SLIDER_DEFAULT_COLOR",
- "SLIDER_HOVER_COLOR",
- "SLIDER_ACTIVE_COLOR",
- "SLIDERBAR_BORDER_COLOR",
- "SLIDERBAR_INSIDE_COLOR",
- "SLIDERBAR_DEFAULT_COLOR",
- "SLIDERBAR_HOVER_COLOR",
- "SLIDERBAR_ACTIVE_COLOR",
- "SLIDERBAR_ZERO_LINE_COLOR",
- "PROGRESSBAR_BORDER_COLOR",
- "PROGRESSBAR_INSIDE_COLOR",
- "PROGRESSBAR_PROGRESS_COLOR",
- "PROGRESSBAR_BORDER_WIDTH",
- "SPINNER_LABEL_BORDER_COLOR",
- "SPINNER_LABEL_INSIDE_COLOR",
- "SPINNER_DEFAULT_BUTTON_BORDER_COLOR",
- "SPINNER_DEFAULT_BUTTON_INSIDE_COLOR",
- "SPINNER_DEFAULT_SYMBOL_COLOR",
- "SPINNER_DEFAULT_TEXT_COLOR",
- "SPINNER_HOVER_BUTTON_BORDER_COLOR",
- "SPINNER_HOVER_BUTTON_INSIDE_COLOR",
- "SPINNER_HOVER_SYMBOL_COLOR",
- "SPINNER_HOVER_TEXT_COLOR",
- "SPINNER_PRESSED_BUTTON_BORDER_COLOR",
- "SPINNER_PRESSED_BUTTON_INSIDE_COLOR",
- "SPINNER_PRESSED_SYMBOL_COLOR",
- "SPINNER_PRESSED_TEXT_COLOR",
- "COMBOBOX_PADDING",
- "COMBOBOX_BUTTON_WIDTH",
- "COMBOBOX_BUTTON_HEIGHT",
- "COMBOBOX_BORDER_WIDTH",
- "COMBOBOX_DEFAULT_BORDER_COLOR",
- "COMBOBOX_DEFAULT_INSIDE_COLOR",
- "COMBOBOX_DEFAULT_TEXT_COLOR",
- "COMBOBOX_DEFAULT_LIST_TEXT_COLOR",
- "COMBOBOX_HOVER_BORDER_COLOR",
- "COMBOBOX_HOVER_INSIDE_COLOR",
- "COMBOBOX_HOVER_TEXT_COLOR",
- "COMBOBOX_HOVER_LIST_TEXT_COLOR",
- "COMBOBOX_PRESSED_BORDER_COLOR",
- "COMBOBOX_PRESSED_INSIDE_COLOR",
- "COMBOBOX_PRESSED_TEXT_COLOR",
- "COMBOBOX_PRESSED_LIST_BORDER_COLOR",
- "COMBOBOX_PRESSED_LIST_INSIDE_COLOR",
- "COMBOBOX_PRESSED_LIST_TEXT_COLOR",
- "CHECKBOX_DEFAULT_BORDER_COLOR",
- "CHECKBOX_DEFAULT_INSIDE_COLOR",
- "CHECKBOX_HOVER_BORDER_COLOR",
- "CHECKBOX_HOVER_INSIDE_COLOR",
- "CHECKBOX_CLICK_BORDER_COLOR",
- "CHECKBOX_CLICK_INSIDE_COLOR",
- "CHECKBOX_STATUS_ACTIVE_COLOR",
- "CHECKBOX_INSIDE_WIDTH",
- "TEXTBOX_BORDER_WIDTH",
- "TEXTBOX_BORDER_COLOR",
- "TEXTBOX_INSIDE_COLOR",
- "TEXTBOX_TEXT_COLOR",
- "TEXTBOX_LINE_COLOR",
- "TEXTBOX_TEXT_FONTSIZE"
-};
-
-//----------------------------------------------------------------------------------
-// Module specific Functions Declaration
-//----------------------------------------------------------------------------------
-static Color ColorMultiply(Color baseColor, float value);
-
-#if defined RAYGUI_STANDALONE
-static Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
-static int GetHexValue(Color color); // Returns hexadecimal value for a Color
-static bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
-static const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
-
-// NOTE: raygui depend on some raylib input and drawing functions
-// TODO: To use raygui as standalone library, those functions must be overwrite by custom ones
-
-// Input management functions
-static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
-static int IsMouseButtonDown(int button) { return 0; }
-static int IsMouseButtonPressed(int button) { return 0; }
-static int IsMouseButtonReleased(int button) { return 0; }
-static int IsMouseButtonUp(int button) { return 0; }
-
-static int GetKeyPressed(void) { return 0; } // NOTE: Only used by GuiTextBox()
-static int IsKeyDown(int key) { return 0; } // NOTE: Only used by GuiSpinner()
-
-// Drawing related functions
-static int MeasureText(const char *text, int fontSize) { return 0; }
-static void DrawText(const char *text, int posX, int posY, int fontSize, Color color) { }
-static void DrawRectangleRec(Rectangle rec, Color color) { }
-static void DrawRectangle(int posX, int posY, int width, int height, Color color) { DrawRectangleRec((Rectangle){ posX, posY, width, height }, color); }
-#endif
-
-//----------------------------------------------------------------------------------
-// Module Functions Definition
-//----------------------------------------------------------------------------------
-
-// Label element, show text
-RAYGUIDEF void GuiLabel(Rectangle bounds, const char *text)
-{
- #define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
-
- GuiLabelEx(bounds, text, GetColor(style[LABEL_TEXT_COLOR]), BLANK, BLANK);
-}
-
-// Label element extended, configurable colors
-RAYGUIDEF void GuiLabelEx(Rectangle bounds, const char *text, Color textColor, Color border, Color inner)
-{
- // Update control
- //--------------------------------------------------------------------
- int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
- int textHeight = style[GLOBAL_TEXT_FONTSIZE];
-
- if (bounds.width < textWidth) bounds.width = textWidth + style[LABEL_TEXT_PADDING];
- if (bounds.height < textHeight) bounds.height = textHeight + style[LABEL_TEXT_PADDING]/2;
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- DrawRectangleRec(bounds, border);
- DrawRectangle(bounds.x + style[LABEL_BORDER_WIDTH], bounds.y + style[LABEL_BORDER_WIDTH], bounds.width - (2 * style[LABEL_BORDER_WIDTH]), bounds.height - (2 * style[LABEL_BORDER_WIDTH]), inner);
- DrawText(text, bounds.x + ((bounds.width/2) - (textWidth/2)), bounds.y + ((bounds.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], textColor);
- //--------------------------------------------------------------------
-}
-
-// Button element, returns true when clicked
-RAYGUIDEF bool GuiButton(Rectangle bounds, const char *text)
-{
- ButtonState buttonState = BUTTON_DEFAULT;
- Vector2 mousePoint = GetMousePosition();
-
- int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
- int textHeight = style[GLOBAL_TEXT_FONTSIZE];
-
- // Update control
- //--------------------------------------------------------------------
- if (bounds.width < textWidth) bounds.width = textWidth + style[BUTTON_TEXT_PADDING];
- if (bounds.height < textHeight) bounds.height = textHeight + style[BUTTON_TEXT_PADDING]/2;
-
- if (CheckCollisionPointRec(mousePoint, bounds))
- {
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) buttonState = BUTTON_PRESSED;
- else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) buttonState = BUTTON_CLICKED;
- else buttonState = BUTTON_HOVER;
- }
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- switch (buttonState)
- {
- case BUTTON_DEFAULT:
- {
- DrawRectangleRec(bounds, GetColor(style[BUTTON_DEFAULT_BORDER_COLOR]));
- DrawRectangle((int)(bounds.x + style[BUTTON_BORDER_WIDTH]), (int)(bounds.y + style[BUTTON_BORDER_WIDTH]) , (int)(bounds.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(bounds.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_DEFAULT_INSIDE_COLOR]));
- DrawText(text, bounds.x + ((bounds.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), bounds.y + ((bounds.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[BUTTON_DEFAULT_TEXT_COLOR]));
- } break;
- case BUTTON_HOVER:
- {
- DrawRectangleRec(bounds, GetColor(style[BUTTON_HOVER_BORDER_COLOR]));
- DrawRectangle((int)(bounds.x + style[BUTTON_BORDER_WIDTH]), (int)(bounds.y + style[BUTTON_BORDER_WIDTH]) , (int)(bounds.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(bounds.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_HOVER_INSIDE_COLOR]));
- DrawText(text, bounds.x + ((bounds.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), bounds.y + ((bounds.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[BUTTON_HOVER_TEXT_COLOR]));
- } break;
- case BUTTON_PRESSED:
- {
- DrawRectangleRec(bounds, GetColor(style[BUTTON_PRESSED_BORDER_COLOR]));
- DrawRectangle((int)(bounds.x + style[BUTTON_BORDER_WIDTH]), (int)(bounds.y + style[BUTTON_BORDER_WIDTH]) , (int)(bounds.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(bounds.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_PRESSED_INSIDE_COLOR]));
- DrawText(text, bounds.x + ((bounds.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), bounds.y + ((bounds.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[BUTTON_PRESSED_TEXT_COLOR]));
- } break;
- case BUTTON_CLICKED:
- {
- DrawRectangleRec(bounds, GetColor(style[BUTTON_PRESSED_BORDER_COLOR]));
- DrawRectangle((int)(bounds.x + style[BUTTON_BORDER_WIDTH]), (int)(bounds.y + style[BUTTON_BORDER_WIDTH]) , (int)(bounds.width - (2 * style[BUTTON_BORDER_WIDTH])), (int)(bounds.height - (2 * style[BUTTON_BORDER_WIDTH])), GetColor(style[BUTTON_PRESSED_INSIDE_COLOR]));
- } break;
- default: break;
- }
- //------------------------------------------------------------------
-
- if (buttonState == BUTTON_CLICKED) return true;
- else return false;
-}
-
-// Toggle Button element, returns true when active
-RAYGUIDEF bool GuiToggleButton(Rectangle bounds, const char *text, bool toggle)
-{
- ToggleState toggleState = TOGGLE_UNACTIVE;
- Rectangle toggleButton = bounds;
- Vector2 mousePoint = GetMousePosition();
-
- int textWidth = MeasureText(text, style[GLOBAL_TEXT_FONTSIZE]);
- int textHeight = style[GLOBAL_TEXT_FONTSIZE];
-
- // Update control
- //--------------------------------------------------------------------
- if (toggleButton.width < textWidth) toggleButton.width = textWidth + style[TOGGLE_TEXT_PADDING];
- if (toggleButton.height < textHeight) toggleButton.height = textHeight + style[TOGGLE_TEXT_PADDING]/2;
-
- if (toggle) toggleState = TOGGLE_ACTIVE;
- else toggleState = TOGGLE_UNACTIVE;
-
- if (CheckCollisionPointRec(mousePoint, toggleButton))
- {
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) toggleState = TOGGLE_PRESSED;
- else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
- {
- if (toggle)
- {
- toggle = false;
- toggleState = TOGGLE_UNACTIVE;
- }
- else
- {
- toggle = true;
- toggleState = TOGGLE_ACTIVE;
- }
- }
- else toggleState = TOGGLE_HOVER;
- }
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- switch (toggleState)
- {
- case TOGGLE_UNACTIVE:
- {
- DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_DEFAULT_BORDER_COLOR]));
- DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_DEFAULT_INSIDE_COLOR]));
- DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_DEFAULT_TEXT_COLOR]));
- } break;
- case TOGGLE_HOVER:
- {
- DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_HOVER_BORDER_COLOR]));
- DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_HOVER_INSIDE_COLOR]));
- DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_HOVER_TEXT_COLOR]));
- } break;
- case TOGGLE_PRESSED:
- {
- DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_PRESSED_BORDER_COLOR]));
- DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_PRESSED_INSIDE_COLOR]));
- DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_PRESSED_TEXT_COLOR]));
- } break;
- case TOGGLE_ACTIVE:
- {
- DrawRectangleRec(toggleButton, GetColor(style[TOGGLE_ACTIVE_BORDER_COLOR]));
- DrawRectangle((int)(toggleButton.x + style[TOGGLE_BORDER_WIDTH]), (int)(toggleButton.y + style[TOGGLE_BORDER_WIDTH]) , (int)(toggleButton.width - (2 * style[TOGGLE_BORDER_WIDTH])), (int)(toggleButton.height - (2 * style[TOGGLE_BORDER_WIDTH])), GetColor(style[TOGGLE_ACTIVE_INSIDE_COLOR]));
- DrawText(text, toggleButton.x + ((toggleButton.width/2) - (MeasureText(text, style[GLOBAL_TEXT_FONTSIZE])/2)), toggleButton.y + ((toggleButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[TOGGLE_ACTIVE_TEXT_COLOR]));
- } break;
- default: break;
- }
- //--------------------------------------------------------------------
-
- return toggle;
-}
-
-// Toggle Group element, returns toggled button index
-RAYGUIDEF int GuiToggleGroup(Rectangle bounds, int toggleNum, char **toggleText, int toggleActive)
-{
- for (int i = 0; i < toggleNum; i++)
- {
- if (i == toggleActive) GuiToggleButton((Rectangle){bounds.x + i*(bounds.width + style[TOGGLEGROUP_PADDING]),bounds.y,bounds.width,bounds.height}, toggleText[i], true);
- else if (GuiToggleButton((Rectangle){bounds.x + i*(bounds.width + style[TOGGLEGROUP_PADDING]),bounds.y,bounds.width,bounds.height}, toggleText[i], false) == true) toggleActive = i;
- }
-
- return toggleActive;
-}
-
-// Combo Box element, returns selected item index
-RAYGUIDEF int GuiComboBox(Rectangle bounds, int comboNum, char **comboText, int comboActive)
-{
- ComboBoxState comboBoxState = COMBOBOX_UNACTIVE;
- Rectangle comboBoxButton = bounds;
- Rectangle click = { bounds.x + bounds.width + style[COMBOBOX_PADDING], bounds.y, style[COMBOBOX_BUTTON_WIDTH], style[COMBOBOX_BUTTON_HEIGHT] };
- Vector2 mousePoint = GetMousePosition();
-
- int textHeight = style[GLOBAL_TEXT_FONTSIZE];
-
- for (int i = 0; i < comboNum; i++)
- {
- if (i == comboActive)
- {
- // Update control
- //--------------------------------------------------------------------
- int textWidth = MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE]);
-
- if (comboBoxButton.width < textWidth) comboBoxButton.width = textWidth + style[TOGGLE_TEXT_PADDING];
- if (comboBoxButton.height < textHeight) comboBoxButton.height = textHeight + style[TOGGLE_TEXT_PADDING]/2;
-
- if (CheckCollisionPointRec(mousePoint, comboBoxButton) || CheckCollisionPointRec(mousePoint, click))
- {
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) comboBoxState = COMBOBOX_PRESSED;
- else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON)) comboBoxState = COMBOBOX_ACTIVE;
- else comboBoxState = COMBOBOX_HOVER;
- }
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- switch (comboBoxState)
- {
- case COMBOBOX_UNACTIVE:
- {
- DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_DEFAULT_BORDER_COLOR]));
- DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_DEFAULT_INSIDE_COLOR]));
-
- DrawRectangleRec(click, GetColor(style[COMBOBOX_DEFAULT_BORDER_COLOR]));
- DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_DEFAULT_INSIDE_COLOR]));
- DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_DEFAULT_LIST_TEXT_COLOR]));
- DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_DEFAULT_TEXT_COLOR]));
- } break;
- case COMBOBOX_HOVER:
- {
- DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_HOVER_BORDER_COLOR]));
- DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_HOVER_INSIDE_COLOR]));
-
- DrawRectangleRec(click, GetColor(style[COMBOBOX_HOVER_BORDER_COLOR]));
- DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_HOVER_INSIDE_COLOR]));
- DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_HOVER_LIST_TEXT_COLOR]));
- DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_HOVER_TEXT_COLOR]));
- } break;
- case COMBOBOX_PRESSED:
- {
- DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_PRESSED_BORDER_COLOR]));
- DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_INSIDE_COLOR]));
-
- DrawRectangleRec(click, GetColor(style[COMBOBOX_PRESSED_LIST_BORDER_COLOR]));
- DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_LIST_INSIDE_COLOR]));
- DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_LIST_TEXT_COLOR]));
- DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_TEXT_COLOR]));
- } break;
- case COMBOBOX_ACTIVE:
- {
- DrawRectangleRec(comboBoxButton, GetColor(style[COMBOBOX_PRESSED_BORDER_COLOR]));
- DrawRectangle((int)(comboBoxButton.x + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.y + style[COMBOBOX_BORDER_WIDTH]), (int)(comboBoxButton.width - (2 * style[COMBOBOX_BORDER_WIDTH])), (int)(comboBoxButton.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_INSIDE_COLOR]));
-
- DrawRectangleRec(click, GetColor(style[COMBOBOX_PRESSED_LIST_BORDER_COLOR]));
- DrawRectangle((int)(click.x + style[COMBOBOX_BORDER_WIDTH]), (int)(click.y + style[COMBOBOX_BORDER_WIDTH]) , (int)(click.width - (2*style[COMBOBOX_BORDER_WIDTH])), (int)(click.height - (2*style[COMBOBOX_BORDER_WIDTH])), GetColor(style[COMBOBOX_PRESSED_LIST_INSIDE_COLOR]));
- DrawText(FormatText("%i/%i", comboActive + 1, comboNum), click.x + ((click.width/2) - (MeasureText(FormatText("%i/%i", comboActive + 1, comboNum), style[GLOBAL_TEXT_FONTSIZE])/2)), click.y + ((click.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_LIST_TEXT_COLOR]));
- DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[GLOBAL_TEXT_FONTSIZE])/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[COMBOBOX_PRESSED_TEXT_COLOR]));
- } break;
- default: break;
- }
-
- //DrawText(comboText[i], comboBoxButton.x + ((comboBoxButton.width/2) - (MeasureText(comboText[i], style[]globalTextFontSize)/2)), comboBoxButton.y + ((comboBoxButton.height/2) - (style[]globalTextFontSize/2)), style[]globalTextFontSize, COMBOBOX_PRESSED_TEXT_COLOR);
- //--------------------------------------------------------------------
- }
- }
-
- if (CheckCollisionPointRec(GetMousePosition(), bounds) || CheckCollisionPointRec(GetMousePosition(), click))
- {
- if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
- {
- comboActive += 1;
- if(comboActive >= comboNum) comboActive = 0;
- }
- }
-
- return comboActive;
-}
-
-// Check Box element, returns true when active
-RAYGUIDEF bool GuiCheckBox(Rectangle checkBoxBounds, const char *text, bool checked)
-{
- CheckBoxState checkBoxState = CHECKBOX_STATUS;
- Vector2 mousePoint = GetMousePosition();
-
- // Update control
- //--------------------------------------------------------------------
- if (CheckCollisionPointRec(mousePoint, checkBoxBounds))
- {
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) checkBoxState = CHECKBOX_PRESSED;
- else if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
- {
- checkBoxState = CHECKBOX_STATUS;
- checked = !checked;
- }
- else checkBoxState = CHECKBOX_HOVER;
- }
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- switch (checkBoxState)
- {
- case CHECKBOX_HOVER:
- {
- DrawRectangleRec(checkBoxBounds, GetColor(style[CHECKBOX_HOVER_BORDER_COLOR]));
- DrawRectangle((int)(checkBoxBounds.x + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxBounds.y + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxBounds.width - (2*style[TOGGLE_BORDER_WIDTH])), (int)(checkBoxBounds.height - (2*style[TOGGLE_BORDER_WIDTH])), GetColor(style[CHECKBOX_HOVER_INSIDE_COLOR]));
- } break;
- case CHECKBOX_STATUS:
- {
- DrawRectangleRec(checkBoxBounds, GetColor(style[CHECKBOX_DEFAULT_BORDER_COLOR]));
- DrawRectangle((int)(checkBoxBounds.x + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxBounds.y + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxBounds.width - (2*style[TOGGLE_BORDER_WIDTH])), (int)(checkBoxBounds.height - (2*style[TOGGLE_BORDER_WIDTH])), GetColor(style[CHECKBOX_DEFAULT_INSIDE_COLOR]));
- } break;
- case CHECKBOX_PRESSED:
- {
- DrawRectangleRec(checkBoxBounds, GetColor(style[CHECKBOX_CLICK_BORDER_COLOR]));
- DrawRectangle((int)(checkBoxBounds.x + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxBounds.y + style[TOGGLE_BORDER_WIDTH]), (int)(checkBoxBounds.width - (2*style[TOGGLE_BORDER_WIDTH])), (int)(checkBoxBounds.height - (2*style[TOGGLE_BORDER_WIDTH])), GetColor(style[CHECKBOX_CLICK_INSIDE_COLOR]));
- } break;
- default: break;
- }
-
- if (text != NULL) DrawText(text, checkBoxBounds.x + checkBoxBounds.width + 2, checkBoxBounds.y + ((checkBoxBounds.height/2) - (style[GLOBAL_TEXT_FONTSIZE]/2) + 1), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[LABEL_TEXT_COLOR]));
-
- if (checked)
- {
- DrawRectangle((int)(checkBoxBounds.x + style[CHECKBOX_INSIDE_WIDTH]), (int)(checkBoxBounds.y + style[CHECKBOX_INSIDE_WIDTH]), (int)(checkBoxBounds.width - (2*style[CHECKBOX_INSIDE_WIDTH])), (int)(checkBoxBounds.height - (2*style[CHECKBOX_INSIDE_WIDTH])), GetColor(style[CHECKBOX_STATUS_ACTIVE_COLOR]));
- }
- //--------------------------------------------------------------------
-
- return checked;
-}
-
-// Slider element, returns selected value
-RAYGUIDEF float GuiSlider(Rectangle bounds, float value, float minValue, float maxValue)
-{
- SliderState sliderState = SLIDER_DEFAULT;
- float buttonTravelDistance = 0;
- float sliderPos = 0;
- Vector2 mousePoint = GetMousePosition();
-
- // Update control
- //--------------------------------------------------------------------
- if (value < minValue) value = minValue;
- else if (value >= maxValue) value = maxValue;
-
- sliderPos = (value - minValue)/(maxValue - minValue);
-
- Rectangle sliderButton;
- sliderButton.width = ((int)(bounds.width - (2 * style[SLIDER_BUTTON_BORDER_WIDTH]))/10 - 8);
- sliderButton.height =((int)(bounds.height - ( 2 * style[SLIDER_BORDER_WIDTH] + 2 * style[SLIDER_BUTTON_BORDER_WIDTH])));
-
- float sliderButtonMinPos = bounds.x + style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH];
- float sliderButtonMaxPos = bounds.x + bounds.width - (style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH] + sliderButton.width);
-
- buttonTravelDistance = sliderButtonMaxPos - sliderButtonMinPos;
-
- sliderButton.x = ((int)(bounds.x + style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH]) + (sliderPos * buttonTravelDistance));
- sliderButton.y = ((int)(bounds.y + style[SLIDER_BORDER_WIDTH] + style[SLIDER_BUTTON_BORDER_WIDTH]));
-
- if (CheckCollisionPointRec(mousePoint, bounds))
- {
- sliderState = SLIDER_HOVER;
-
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON)) sliderState = SLIDER_ACTIVE;
-
- if ((sliderState == SLIDER_ACTIVE) && (IsMouseButtonDown(MOUSE_LEFT_BUTTON)))
- {
- sliderButton.x = mousePoint.x - sliderButton.width / 2;
-
- if (sliderButton.x <= sliderButtonMinPos) sliderButton.x = sliderButtonMinPos;
- else if (sliderButton.x >= sliderButtonMaxPos) sliderButton.x = sliderButtonMaxPos;
-
- sliderPos = (sliderButton.x - sliderButtonMinPos) / buttonTravelDistance;
- }
- }
- else sliderState = SLIDER_DEFAULT;
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- DrawRectangleRec(bounds, GetColor(style[SLIDER_BORDER_COLOR]));
- DrawRectangle((int)(bounds.x + style[SLIDER_BORDER_WIDTH]), (int)(bounds.y + style[SLIDER_BORDER_WIDTH]), (int)(bounds.width - (2*style[SLIDER_BORDER_WIDTH])), (int)(bounds.height - (2*style[SLIDER_BORDER_WIDTH])), GetColor(style[SLIDER_INSIDE_COLOR]));
-
- switch (sliderState)
- {
- case SLIDER_DEFAULT: DrawRectangleRec(sliderButton, GetColor(style[SLIDER_DEFAULT_COLOR])); break;
- case SLIDER_HOVER: DrawRectangleRec(sliderButton, GetColor(style[SLIDER_HOVER_COLOR])); break;
- case SLIDER_ACTIVE: DrawRectangleRec(sliderButton, GetColor(style[SLIDER_ACTIVE_COLOR])); break;
- default: break;
- }
- //--------------------------------------------------------------------
-
- return minValue + (maxValue - minValue)*sliderPos;
-}
-
-// Slider Bar element, returns selected value
-RAYGUIDEF float GuiSliderBar(Rectangle bounds, float value, float minValue, float maxValue)
-{
- SliderState sliderState = SLIDER_DEFAULT;
- Vector2 mousePoint = GetMousePosition();
- float fixedValue;
- float fixedMinValue;
-
- fixedValue = value - minValue;
- maxValue = maxValue - minValue;
- fixedMinValue = 0;
-
- // Update control
- //--------------------------------------------------------------------
- if (fixedValue <= fixedMinValue) fixedValue = fixedMinValue;
- else if (fixedValue >= maxValue) fixedValue = maxValue;
-
- Rectangle sliderBar;
-
- sliderBar.x = bounds.x + style[SLIDER_BORDER_WIDTH];
- sliderBar.y = bounds.y + style[SLIDER_BORDER_WIDTH];
- sliderBar.width = ((fixedValue*((float)bounds.width - 2*style[SLIDER_BORDER_WIDTH]))/(maxValue - fixedMinValue));
- sliderBar.height = bounds.height - 2*style[SLIDER_BORDER_WIDTH];
-
- if (CheckCollisionPointRec(mousePoint, bounds))
- {
- sliderState = SLIDER_HOVER;
-
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
- {
- sliderState = SLIDER_ACTIVE;
-
- sliderBar.width = (mousePoint.x - bounds.x - style[SLIDER_BORDER_WIDTH]);
-
- if (mousePoint.x <= (bounds.x + style[SLIDER_BORDER_WIDTH])) sliderBar.width = 0;
- else if (mousePoint.x >= (bounds.x + bounds.width - style[SLIDER_BORDER_WIDTH])) sliderBar.width = bounds.width - 2*style[SLIDER_BORDER_WIDTH];
- }
- }
- else sliderState = SLIDER_DEFAULT;
-
- fixedValue = ((float)sliderBar.width*(maxValue - fixedMinValue))/((float)bounds.width - 2*style[SLIDER_BORDER_WIDTH]);
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- DrawRectangleRec(bounds, GetColor(style[SLIDERBAR_BORDER_COLOR]));
- DrawRectangle((int)(bounds.x + style[SLIDER_BORDER_WIDTH]), (int)(bounds.y + style[SLIDER_BORDER_WIDTH]) , (int)(bounds.width - (2*style[SLIDER_BORDER_WIDTH])), (int)(bounds.height - (2*style[SLIDER_BORDER_WIDTH])), GetColor(style[SLIDERBAR_INSIDE_COLOR]));
-
- switch (sliderState)
- {
- case SLIDER_DEFAULT: DrawRectangleRec(sliderBar, GetColor(style[SLIDERBAR_DEFAULT_COLOR])); break;
- case SLIDER_HOVER: DrawRectangleRec(sliderBar, GetColor(style[SLIDERBAR_HOVER_COLOR])); break;
- case SLIDER_ACTIVE: DrawRectangleRec(sliderBar, GetColor(style[SLIDERBAR_ACTIVE_COLOR])); break;
- default: break;
- }
-
- if (minValue < 0 && maxValue > 0) DrawRectangle((bounds.x + style[SLIDER_BORDER_WIDTH]) - (minValue * ((bounds.width - (style[SLIDER_BORDER_WIDTH]*2))/maxValue)), sliderBar.y, 1, sliderBar.height, GetColor(style[SLIDERBAR_ZERO_LINE_COLOR]));
- //--------------------------------------------------------------------
-
- return fixedValue + minValue;
-}
-
-// Progress Bar element, shows current progress value
-RAYGUIDEF void GuiProgressBar(Rectangle bounds, float value)
-{
- if (value > 1.0f) value = 1.0f;
- else if (value < 0.0f) value = 0.0f;
-
- Rectangle progressBar = { bounds.x + style[PROGRESSBAR_BORDER_WIDTH], bounds.y + style[PROGRESSBAR_BORDER_WIDTH], bounds.width - (style[PROGRESSBAR_BORDER_WIDTH] * 2), bounds.height - (style[PROGRESSBAR_BORDER_WIDTH] * 2)};
- Rectangle progressValue = { bounds.x + style[PROGRESSBAR_BORDER_WIDTH], bounds.y + style[PROGRESSBAR_BORDER_WIDTH], value * (bounds.width - (style[PROGRESSBAR_BORDER_WIDTH] * 2)), bounds.height - (style[PROGRESSBAR_BORDER_WIDTH] * 2)};
-
- // Draw control
- //--------------------------------------------------------------------
- DrawRectangleRec(bounds, GetColor(style[PROGRESSBAR_BORDER_COLOR]));
- DrawRectangleRec(progressBar, GetColor(style[PROGRESSBAR_INSIDE_COLOR]));
- DrawRectangleRec(progressValue, GetColor(style[PROGRESSBAR_PROGRESS_COLOR]));
- //--------------------------------------------------------------------
-}
-
-// Spinner element, returns selected value
-// NOTE: Requires static variables: framesCounter, valueSpeed - ERROR!
-RAYGUIDEF int GuiSpinner(Rectangle bounds, int value, int minValue, int maxValue)
-{
- SpinnerState spinnerState = SPINNER_DEFAULT;
- Rectangle labelBoxBound = { bounds.x + bounds.width/4 + 1, bounds.y, bounds.width/2, bounds.height };
- Rectangle leftButtonBound = { bounds.x, bounds.y, bounds.width/4, bounds.height };
- Rectangle rightButtonBound = { bounds.x + bounds.width - bounds.width/4 + 1, bounds.y, bounds.width/4, bounds.height };
- Vector2 mousePoint = GetMousePosition();
-
- int textWidth = MeasureText(FormatText("%i", value), style[GLOBAL_TEXT_FONTSIZE]);
- //int textHeight = style[GLOBAL_TEXT_FONTSIZE]; // Unused variable
-
- int buttonSide = 0;
-
- static int framesCounter = 0;
- static bool valueSpeed = false;;
-
- //if (comboBoxButton.width < textWidth) comboBoxButton.width = textWidth + style[TOGGLE_TEXT_PADDING];
- //if (comboBoxButton.height < textHeight) comboBoxButton.height = textHeight + style[TOGGLE_TEXT_PADDING]/2;
-
- // Update control
- //--------------------------------------------------------------------
- if (CheckCollisionPointRec(mousePoint, leftButtonBound) || CheckCollisionPointRec(mousePoint, rightButtonBound) || CheckCollisionPointRec(mousePoint, labelBoxBound))
- {
- if (IsKeyDown(KEY_LEFT))
- {
- spinnerState = SPINNER_PRESSED;
- buttonSide = 1;
-
- if (value > minValue) value -= 1;
- }
- else if (IsKeyDown(KEY_RIGHT))
- {
- spinnerState = SPINNER_PRESSED;
- buttonSide = 2;
-
- if (value < maxValue) value += 1;
- }
- }
-
- if (CheckCollisionPointRec(mousePoint, leftButtonBound))
- {
- buttonSide = 1;
- spinnerState = SPINNER_HOVER;
-
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
- {
- if (!valueSpeed)
- {
- if (value > minValue) value--;
- valueSpeed = true;
- }
- else framesCounter++;
-
- spinnerState = SPINNER_PRESSED;
-
- if (value > minValue)
- {
- if (framesCounter >= 30) value -= 1;
- }
- }
- }
- else if (CheckCollisionPointRec(mousePoint, rightButtonBound))
- {
- buttonSide = 2;
- spinnerState = SPINNER_HOVER;
-
- if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
- {
- if (!valueSpeed)
- {
- if (value < maxValue) value++;
- valueSpeed = true;
- }
- else framesCounter++;
-
- spinnerState = SPINNER_PRESSED;
-
- if (value < maxValue)
- {
- if (framesCounter >= 30) value += 1;
- }
- }
- }
- else if (!CheckCollisionPointRec(mousePoint, labelBoxBound)) buttonSide = 0;
-
- if (IsMouseButtonUp(MOUSE_LEFT_BUTTON))
- {
- valueSpeed = false;
- framesCounter = 0;
- }
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- switch (spinnerState)
- {
- case SPINNER_DEFAULT:
- {
- DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR]));
- DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR]));
-
- DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR]));
- DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR]));
-
- DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR]));
- DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR]));
-
- DrawRectangleRec(labelBoxBound, GetColor(style[SPINNER_LABEL_BORDER_COLOR]));
- DrawRectangle(labelBoxBound.x + 1, labelBoxBound.y + 1, labelBoxBound.width - 2, labelBoxBound.height - 2, GetColor(style[SPINNER_LABEL_INSIDE_COLOR]));
-
- DrawText(FormatText("%i", value), labelBoxBound.x + (labelBoxBound.width/2 - textWidth/2), labelBoxBound.y + (labelBoxBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_TEXT_COLOR]));
- } break;
- case SPINNER_HOVER:
- {
- if (buttonSide == 1)
- {
- DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_HOVER_BUTTON_BORDER_COLOR]));
- DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_HOVER_BUTTON_INSIDE_COLOR]));
-
- DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR]));
- DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR]));
-
- DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_HOVER_SYMBOL_COLOR]));
- DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR]));
- }
- else if (buttonSide == 2)
- {
- DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR]));
- DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR]));
-
- DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_HOVER_BUTTON_BORDER_COLOR]));
- DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_HOVER_BUTTON_INSIDE_COLOR]));
-
- DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR]));
- DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_HOVER_SYMBOL_COLOR]));
- }
-
- DrawRectangleRec(labelBoxBound, GetColor(style[SPINNER_LABEL_BORDER_COLOR]));
- DrawRectangle(labelBoxBound.x + 1, labelBoxBound.y + 1, labelBoxBound.width - 2, labelBoxBound.height - 2, GetColor(style[SPINNER_LABEL_INSIDE_COLOR]));
-
- DrawText(FormatText("%i", value), labelBoxBound.x + (labelBoxBound.width/2 - textWidth/2), labelBoxBound.y + (labelBoxBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_HOVER_TEXT_COLOR]));
- } break;
- case SPINNER_PRESSED:
- {
- if (buttonSide == 1)
- {
- DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_PRESSED_BUTTON_BORDER_COLOR]));
- DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_PRESSED_BUTTON_INSIDE_COLOR]));
-
- DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR]));
- DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR]));
-
- DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_PRESSED_SYMBOL_COLOR]));
- DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR]));
- }
- else if (buttonSide == 2)
- {
- DrawRectangleRec(leftButtonBound, GetColor(style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR]));
- DrawRectangle(leftButtonBound.x + 2, leftButtonBound.y + 2, leftButtonBound.width - 4, leftButtonBound.height - 4, GetColor(style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR]));
-
- DrawRectangleRec(rightButtonBound, GetColor(style[SPINNER_PRESSED_BUTTON_BORDER_COLOR]));
- DrawRectangle(rightButtonBound.x + 2, rightButtonBound.y + 2, rightButtonBound.width - 4, rightButtonBound.height - 4, GetColor(style[SPINNER_PRESSED_BUTTON_INSIDE_COLOR]));
-
- DrawText(FormatText("-"), leftButtonBound.x + (leftButtonBound.width/2 - (MeasureText(FormatText("+"), style[GLOBAL_TEXT_FONTSIZE]))/2), leftButtonBound.y + (leftButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_DEFAULT_SYMBOL_COLOR]));
- DrawText(FormatText("+"), rightButtonBound.x + (rightButtonBound.width/2 - (MeasureText(FormatText("-"), style[GLOBAL_TEXT_FONTSIZE]))/2), rightButtonBound.y + (rightButtonBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_PRESSED_SYMBOL_COLOR]));
- }
-
- DrawRectangleRec(labelBoxBound, GetColor(style[SPINNER_LABEL_BORDER_COLOR]));
- DrawRectangle(labelBoxBound.x + 1, labelBoxBound.y + 1, labelBoxBound.width - 2, labelBoxBound.height - 2, GetColor(style[SPINNER_LABEL_INSIDE_COLOR]));
-
- DrawText(FormatText("%i", value), labelBoxBound.x + (labelBoxBound.width/2 - textWidth/2), labelBoxBound.y + (labelBoxBound.height/2 - (style[GLOBAL_TEXT_FONTSIZE]/2)), style[GLOBAL_TEXT_FONTSIZE], GetColor(style[SPINNER_PRESSED_TEXT_COLOR]));
- } break;
- default: break;
- }
-
- return value;
-}
-
-// Text Box element, returns input text
-// NOTE: Requires static variables: framesCounter - ERROR!
-RAYGUIDEF char *GuiTextBox(Rectangle bounds, char *text)
-{
- #define MAX_CHARS_LENGTH 20
- #define KEY_BACKSPACE_TEXT 259 // GLFW BACKSPACE: 3 + 256
-
- int initPos = bounds.x + 4;
- int letter = -1;
- static int framesCounter = 0;
- Vector2 mousePoint = GetMousePosition();
-
- // Update control
- //--------------------------------------------------------------------
- framesCounter++;
-
- letter = GetKeyPressed();
-
- if (CheckCollisionPointRec(mousePoint, bounds))
- {
- if (letter != -1)
- {
- if (letter == KEY_BACKSPACE_TEXT)
- {
- for (int i = 0; i < MAX_CHARS_LENGTH; i++)
- {
- if ((text[i] == '\0') && (i > 0))
- {
- text[i - 1] = '\0';
- break;
- }
- }
-
- text[MAX_CHARS_LENGTH - 1] = '\0';
- }
- else
- {
- if ((letter >= 32) && (letter < 127))
- {
- for (int i = 0; i < MAX_CHARS_LENGTH; i++)
- {
- if (text[i] == '\0')
- {
- text[i] = (char)letter;
- break;
- }
- }
- }
- }
- }
- }
- //--------------------------------------------------------------------
-
- // Draw control
- //--------------------------------------------------------------------
- if (CheckCollisionPointRec(mousePoint, bounds)) DrawRectangleRec(bounds, GetColor(style[TOGGLE_ACTIVE_BORDER_COLOR]));
- else DrawRectangleRec(bounds, GetColor(style[TEXTBOX_BORDER_COLOR]));
-
- DrawRectangle(bounds.x + style[TEXTBOX_BORDER_WIDTH], bounds.y + style[TEXTBOX_BORDER_WIDTH], bounds.width - (style[TEXTBOX_BORDER_WIDTH] * 2), bounds.height - (style[TEXTBOX_BORDER_WIDTH] * 2), GetColor(style[TEXTBOX_INSIDE_COLOR]));
-
- for (int i = 0; i < MAX_CHARS_LENGTH; i++)
- {
- if (text[i] == '\0') break;
-
- DrawText(FormatText("%c", text[i]), initPos, bounds.y + style[TEXTBOX_TEXT_FONTSIZE], style[TEXTBOX_TEXT_FONTSIZE], GetColor(style[TEXTBOX_TEXT_COLOR]));
-
- initPos += (MeasureText(FormatText("%c", text[i]), style[GLOBAL_TEXT_FONTSIZE]) + 2);
- //initPos += ((GetDefaultFont().charRecs[(int)text[i] - 32].width + 2));
- }
-
- if ((framesCounter/20)%2 && CheckCollisionPointRec(mousePoint, bounds)) DrawRectangle(initPos + 2, bounds.y + 5, 1, 20, GetColor(style[TEXTBOX_LINE_COLOR]));
- //--------------------------------------------------------------------
-
- return text;
-}
-
-// Save current GUI style into a text file
-RAYGUIDEF void SaveGuiStyle(const char *fileName)
-{
- FILE *styleFile = fopen(fileName, "wt");
-
- for (int i = 0; i < NUM_PROPERTIES; i++) fprintf(styleFile, "%-40s0x%x\n", guiPropertyName[i], GetStyleProperty(i));
-
- fclose(styleFile);
-}
-
-// Load GUI style from a text file
-RAYGUIDEF void LoadGuiStyle(const char *fileName)
-{
- #define MAX_STYLE_PROPERTIES 128
-
- typedef struct {
- char id[64];
- int value;
- } StyleProperty;
-
- StyleProperty *styleProp = (StyleProperty *)RAYGUI_MALLOC(MAX_STYLE_PROPERTIES*sizeof(StyleProperty));;
- int counter = 0;
-
- FILE *styleFile = fopen(fileName, "rt");
-
- while (!feof(styleFile))
- {
- fscanf(styleFile, "%s %i\n", styleProp[counter].id, &styleProp[counter].value);
- counter++;
- }
-
- fclose(styleFile);
-
- for (int i = 0; i < counter; i++)
- {
- for (int j = 0; j < NUM_PROPERTIES; j++)
- {
- if (strcmp(styleProp[i].id, guiPropertyName[j]) == 0)
- {
- // Assign correct property to style
- style[j] = styleProp[i].value;
- }
- }
- }
-
- RAYGUI_FREE(styleProp);
-}
-
-// Set one style property value
-RAYGUIDEF void SetStyleProperty(int guiProperty, int value)
-{
- #define NUM_COLOR_SAMPLES 10
-
- if (guiProperty == GLOBAL_BASE_COLOR)
- {
- Color baseColor = GetColor(value);
- Color fadeColor[NUM_COLOR_SAMPLES];
-
- for (int i = 0; i < NUM_COLOR_SAMPLES; i++) fadeColor[i] = ColorMultiply(baseColor, 1.0f - (float)i/(NUM_COLOR_SAMPLES - 1));
-
- style[GLOBAL_BASE_COLOR] = value;
- style[BACKGROUND_COLOR] = GetHexValue(fadeColor[3]);
- style[BUTTON_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[BUTTON_HOVER_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[BUTTON_PRESSED_INSIDE_COLOR] = GetHexValue(fadeColor[5]);
- style[TOGGLE_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[TOGGLE_HOVER_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[TOGGLE_PRESSED_INSIDE_COLOR] = GetHexValue(fadeColor[5]);
- style[TOGGLE_ACTIVE_INSIDE_COLOR] = GetHexValue(fadeColor[8]);
- style[SLIDER_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[SLIDER_DEFAULT_COLOR] = GetHexValue(fadeColor[6]);
- style[SLIDER_HOVER_COLOR] = GetHexValue(fadeColor[7]);
- style[SLIDER_ACTIVE_COLOR] = GetHexValue(fadeColor[9]);
- style[SLIDERBAR_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[SLIDERBAR_DEFAULT_COLOR] = GetHexValue(fadeColor[6]);
- style[SLIDERBAR_HOVER_COLOR] = GetHexValue(fadeColor[7]);
- style[SLIDERBAR_ACTIVE_COLOR] = GetHexValue(fadeColor[9]);
- style[SLIDERBAR_ZERO_LINE_COLOR] = GetHexValue(fadeColor[8]);
- style[PROGRESSBAR_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[PROGRESSBAR_PROGRESS_COLOR] = GetHexValue(fadeColor[6]);
- style[SPINNER_LABEL_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[SPINNER_DEFAULT_BUTTON_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[SPINNER_HOVER_BUTTON_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[SPINNER_PRESSED_BUTTON_INSIDE_COLOR] = GetHexValue(fadeColor[5]);
- style[COMBOBOX_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[COMBOBOX_HOVER_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[COMBOBOX_PRESSED_INSIDE_COLOR] = GetHexValue(fadeColor[8]);
- style[COMBOBOX_PRESSED_LIST_INSIDE_COLOR] = GetHexValue(fadeColor[8]);
- style[CHECKBOX_DEFAULT_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- style[CHECKBOX_CLICK_INSIDE_COLOR] = GetHexValue(fadeColor[6]);
- style[CHECKBOX_STATUS_ACTIVE_COLOR] = GetHexValue(fadeColor[8]);
- style[TEXTBOX_INSIDE_COLOR] = GetHexValue(fadeColor[4]);
- }
- else if (guiProperty == GLOBAL_BORDER_COLOR)
- {
- Color baseColor = GetColor(value);
- Color fadeColor[NUM_COLOR_SAMPLES];
-
- for (int i = 0; i < NUM_COLOR_SAMPLES; i++) fadeColor[i] = ColorMultiply(baseColor, 1.0f - (float)i/(NUM_COLOR_SAMPLES - 1));
-
- style[GLOBAL_BORDER_COLOR] = value;
- style[BUTTON_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[BUTTON_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]);
- style[BUTTON_PRESSED_BORDER_COLOR] = GetHexValue(fadeColor[9]);
- style[TOGGLE_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[TOGGLE_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]);
- style[TOGGLE_PRESSED_BORDER_COLOR] = GetHexValue(fadeColor[9]);
- style[TOGGLE_ACTIVE_BORDER_COLOR] = GetHexValue(fadeColor[9]);
- style[SLIDER_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[SLIDERBAR_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[PROGRESSBAR_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[SPINNER_LABEL_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[SPINNER_DEFAULT_BUTTON_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[SPINNER_HOVER_BUTTON_BORDER_COLOR] = GetHexValue(fadeColor[8]);
- style[SPINNER_PRESSED_BUTTON_BORDER_COLOR] = GetHexValue(fadeColor[9]);
- style[COMBOBOX_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[COMBOBOX_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]);
- style[COMBOBOX_PRESSED_BORDER_COLOR] = GetHexValue(fadeColor[9]);
- style[COMBOBOX_PRESSED_LIST_BORDER_COLOR] = GetHexValue(fadeColor[9]);
- style[CHECKBOX_DEFAULT_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- style[CHECKBOX_HOVER_BORDER_COLOR] = GetHexValue(fadeColor[8]);
- style[CHECKBOX_CLICK_BORDER_COLOR] = GetHexValue(fadeColor[9]);
- style[TEXTBOX_BORDER_COLOR] = GetHexValue(fadeColor[7]);
- }
- else if (guiProperty == GLOBAL_TEXT_COLOR)
- {
- Color baseColor = GetColor(value);
- Color fadeColor[NUM_COLOR_SAMPLES];
-
- for (int i = 0; i < NUM_COLOR_SAMPLES; i++) fadeColor[i] = ColorMultiply(baseColor, 1.0f - (float)i/(NUM_COLOR_SAMPLES - 1));
-
- style[GLOBAL_TEXT_COLOR] = value;
- style[LABEL_TEXT_COLOR] = GetHexValue(fadeColor[9]);
- style[BUTTON_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]);
- style[BUTTON_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]);
- style[BUTTON_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[5]);
- style[TOGGLE_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]);
- style[TOGGLE_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]);
- style[TOGGLE_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[5]);
- style[TOGGLE_ACTIVE_TEXT_COLOR] = GetHexValue(fadeColor[5]);
- style[SPINNER_DEFAULT_SYMBOL_COLOR] = GetHexValue(fadeColor[9]);
- style[SPINNER_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]);
- style[SPINNER_HOVER_SYMBOL_COLOR] = GetHexValue(fadeColor[8]);
- style[SPINNER_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]);
- style[SPINNER_PRESSED_SYMBOL_COLOR] = GetHexValue(fadeColor[5]);
- style[SPINNER_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[5]);
- style[COMBOBOX_DEFAULT_TEXT_COLOR] = GetHexValue(fadeColor[9]);
- style[COMBOBOX_DEFAULT_LIST_TEXT_COLOR] = GetHexValue(fadeColor[9]);
- style[COMBOBOX_HOVER_TEXT_COLOR] = GetHexValue(fadeColor[8]);
- style[COMBOBOX_HOVER_LIST_TEXT_COLOR] = GetHexValue(fadeColor[8]);
- style[COMBOBOX_PRESSED_TEXT_COLOR] = GetHexValue(fadeColor[4]);
- style[COMBOBOX_PRESSED_LIST_TEXT_COLOR] = GetHexValue(fadeColor[4]);
- style[TEXTBOX_TEXT_COLOR] = GetHexValue(fadeColor[9]);
- style[TEXTBOX_LINE_COLOR] = GetHexValue(fadeColor[6]);
- }
- else style[guiProperty] = value;
-
-}
-
-// Get one style property value
-RAYGUIDEF int GetStyleProperty(int guiProperty) { return style[guiProperty]; }
-
-//----------------------------------------------------------------------------------
-// Module specific Functions Definition
-//----------------------------------------------------------------------------------
-
-static Color ColorMultiply(Color baseColor, float value)
-{
- Color multColor = baseColor;
-
- if (value > 1.0f) value = 1.0f;
- else if (value < 0.0f) value = 0.0f;
-
- multColor.r += (255 - multColor.r)*value;
- multColor.g += (255 - multColor.g)*value;
- multColor.b += (255 - multColor.b)*value;
-
- return multColor;
-}
-
-#if defined (RAYGUI_STANDALONE)
-// Returns a Color struct from hexadecimal value
-static Color GetColor(int hexValue)
-{
- Color color;
-
- color.r = (unsigned char)(hexValue >> 24) & 0xFF;
- color.g = (unsigned char)(hexValue >> 16) & 0xFF;
- color.b = (unsigned char)(hexValue >> 8) & 0xFF;
- color.a = (unsigned char)hexValue & 0xFF;
-
- return color;
-}
-
-// Returns hexadecimal value for a Color
-static int GetHexValue(Color color)
-{
- return (((int)color.r << 24) | ((int)color.g << 16) | ((int)color.b << 8) | (int)color.a);
-}
-
-// Check if point is inside rectangle
-static bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
-{
- bool collision = false;
-
- if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) && (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true;
-
- return collision;
-}
-
-// Formatting of text with variables to 'embed'
-static const char *FormatText(const char *text, ...)
-{
- #define MAX_FORMATTEXT_LENGTH 64
-
- static char buffer[MAX_FORMATTEXT_LENGTH];
-
- va_list args;
- va_start(args, text);
- vsprintf(buffer, text, args);
- va_end(args);
-
- return buffer;
-}
-#endif
-
-#endif // RAYGUI_IMPLEMENTATION
-
diff --git a/src/raylib.h b/src/raylib.h
index 19c67712..e6e510a9 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
-* raylib 1.5.0 (www.raylib.com)
+* raylib 1.6.0 (www.raylib.com)
*
* A simple and easy-to-use library to learn videogames programming
*
@@ -81,6 +81,14 @@
typedef struct android_app; // Define android_app struct (android_native_app_glue.h)
#endif
+#if defined(_WIN32) && defined(BUILDING_DLL)
+ #define RLAPI __declspec(dllexport) // We are building raylib as a Win32 DLL
+#elif defined(_WIN32) && defined(RAYLIB_DLL)
+ #define RLAPI __declspec(dllimport) // We are using raylib as a Win32 DLL
+#else
+ #define RLAPI // We are building or using raylib as a static library (or Linux shared library)
+#endif
+
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
@@ -93,11 +101,12 @@
// raylib Config Flags
#define FLAG_FULLSCREEN_MODE 1
-#define FLAG_SHOW_LOGO 2
-#define FLAG_SHOW_MOUSE_CURSOR 4
-#define FLAG_CENTERED_MODE 8
-#define FLAG_MSAA_4X_HINT 16
-#define FLAG_VSYNC_HINT 32
+#define FLAG_RESIZABLE_WINDOW 2
+#define FLAG_SHOW_LOGO 4
+#define FLAG_SHOW_MOUSE_CURSOR 8
+#define FLAG_CENTERED_MODE 16
+#define FLAG_MSAA_4X_HINT 32
+#define FLAG_VSYNC_HINT 64
// Keyboard Function Keys
#define KEY_SPACE 32
@@ -185,17 +194,20 @@
#define GAMEPAD_PLAYER4 3 // Not supported
// Gamepad Buttons
-// NOTE: Adjusted for a PS3 USB Controller
-#define GAMEPAD_BUTTON_A 2
-#define GAMEPAD_BUTTON_B 1
-#define GAMEPAD_BUTTON_X 3
-#define GAMEPAD_BUTTON_Y 4
-#define GAMEPAD_BUTTON_R1 7
-#define GAMEPAD_BUTTON_R2 5
-#define GAMEPAD_BUTTON_L1 6
-#define GAMEPAD_BUTTON_L2 8
-#define GAMEPAD_BUTTON_SELECT 9
-#define GAMEPAD_BUTTON_START 10
+
+// PS3 USB Controller
+#define GAMEPAD_PS3_BUTTON_A 2
+#define GAMEPAD_PS3_BUTTON_B 1
+#define GAMEPAD_PS3_BUTTON_X 3
+#define GAMEPAD_PS3_BUTTON_Y 4
+#define GAMEPAD_PS3_BUTTON_R1 7
+#define GAMEPAD_PS3_BUTTON_R2 5
+#define GAMEPAD_PS3_BUTTON_L1 6
+#define GAMEPAD_PS3_BUTTON_L2 8
+#define GAMEPAD_PS3_BUTTON_SELECT 9
+#define GAMEPAD_PS3_BUTTON_START 10
+
+// TODO: Add PS3 d-pad axis
// Xbox360 USB Controller Buttons
#define GAMEPAD_XBOX_BUTTON_A 0
@@ -233,44 +245,56 @@
#define ANDROID_VOLUME_UP 24
#define ANDROID_VOLUME_DOWN 25
+// 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 (Color){ 200, 200, 200, 255 } // Light Gray
-#define GRAY (Color){ 130, 130, 130, 255 } // Gray
-#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
-#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
-#define GOLD (Color){ 255, 203, 0, 255 } // Gold
-#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
-#define PINK (Color){ 255, 109, 194, 255 } // Pink
-#define RED (Color){ 230, 41, 55, 255 } // Red
-#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
-#define GREEN (Color){ 0, 228, 48, 255 } // Green
-#define LIME (Color){ 0, 158, 47, 255 } // Lime
-#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
-#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
-#define BLUE (Color){ 0, 121, 241, 255 } // Blue
-#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
-#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
-#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
-#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
-#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
-#define BROWN (Color){ 127, 106, 79, 255 } // Brown
-#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
-
-#define WHITE (Color){ 255, 255, 255, 255 } // White
-#define BLACK (Color){ 0, 0, 0, 255 } // Black
-#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
-#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
-#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
+#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)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
- #if !defined(_STDBOOL_H)
- typedef enum { false, true } bool;
- #define _STDBOOL_H
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
#endif
#endif
@@ -393,7 +417,7 @@ typedef struct Mesh {
// Shader type (generic shader)
typedef struct Shader {
unsigned int id; // Shader program id
-
+
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
@@ -404,8 +428,10 @@ typedef struct Shader {
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
- int tintColorLoc; // Diffuse color uniform location point (fragment shader)
-
+ int colDiffuseLoc; // Diffuse color uniform location point (fragment shader)
+ int colAmbientLoc; // Ambient color uniform location point (fragment shader)
+ int colSpecularLoc; // Specular color uniform location point (fragment shader)
+
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
@@ -419,11 +445,11 @@ typedef struct Material {
Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc)
Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
-
+
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
-
+
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material;
@@ -439,14 +465,14 @@ typedef struct LightData {
unsigned int id; // Light unique id
bool enabled; // Light enabled
int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
-
+
Vector3 position; // Light position
- Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
+ Vector3 target; // Light direction: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Light attenuation radius light intensity reduced with distance (world distance)
-
+
Color diffuse; // Light diffuse color
float intensity; // Light intensity level
-
+
float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light;
@@ -459,21 +485,38 @@ typedef struct Ray {
Vector3 direction; // Ray direction
} Ray;
-// Sound source type
-typedef struct Sound {
- unsigned int source; // Sound audio source id
- unsigned int buffer; // Sound audio buffer id
-} Sound;
-
// 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
- unsigned int dataSize; // Data size in bytes
- unsigned int sampleRate; // Samples per second to be played
- short bitsPerSample; // Sample size in bits
- short channels;
} 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;
+
// Texture formats
// NOTE: Support depends on OpenGL version and platform
typedef enum {
@@ -516,20 +559,14 @@ typedef enum {
GESTURE_PINCH_OUT = 512
} Gestures;
-// Touch action (fingers or mouse)
-typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
-
-// Gesture events
-// NOTE: MAX_TOUCH_POINTS fixed to 2
-typedef struct GestureEvent {
- int touchAction;
- int pointCount;
- int pointerId[MAX_TOUCH_POINTS];
- Vector2 position[MAX_TOUCH_POINTS];
-} GestureEvent;
-
// Camera system modes
-typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
+typedef enum {
+ CAMERA_CUSTOM = 0,
+ CAMERA_FREE,
+ CAMERA_ORBITAL,
+ CAMERA_FIRST_PERSON,
+ CAMERA_THIRD_PERSON
+} CameraMode;
// Head Mounted Display devices
typedef enum {
@@ -557,94 +594,94 @@ extern "C" { // Prevents name mangling of functions
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
-void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
+RLAPI void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
+RLAPI void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
#endif
-void CloseWindow(void); // Close Window and Terminate Context
-bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
-bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
-void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
-int GetScreenWidth(void); // Get current screen width
-int GetScreenHeight(void); // Get current screen height
-
-void ShowCursor(void); // Shows cursor
-void HideCursor(void); // Hides cursor
-bool IsCursorHidden(void); // Returns true if cursor is not visible
-void EnableCursor(void); // Enables cursor
-void DisableCursor(void); // Disables cursor
-
-void ClearBackground(Color color); // Sets Background Color
-void BeginDrawing(void); // Setup drawing canvas to start drawing
-void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
-
-void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera
-void End2dMode(void); // Ends 2D mode custom camera usage
-void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup)
-void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
-void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
-void EndTextureMode(void); // Ends drawing to render texture
-
-Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
-Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position
-Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
-
-void SetTargetFPS(int fps); // Set target FPS (maximum)
-float GetFPS(void); // Returns current FPS
-float GetFrameTime(void); // Returns time in seconds for one frame
-
-Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
-int GetHexValue(Color color); // Returns hexadecimal value for a Color
-float *ColorToFloat(Color color); // Converts Color to float array and normalizes
-float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array
-float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
-
-int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
-Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
-
-void SetConfigFlags(char flags); // Setup some window configuration flags
-void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
-
-bool IsFileDropped(void); // Check if a file have been dropped into window
-char **GetDroppedFiles(int *count); // Retrieve dropped files into window
-void ClearDroppedFiles(void); // Clear dropped files paths buffer
-
-void StorageSaveValue(int position, int value); // Storage save integer value (to defined position)
-int StorageLoadValue(int position); // Storage load integer value (from defined position)
+RLAPI void CloseWindow(void); // Close Window and Terminate Context
+RLAPI bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
+RLAPI bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
+RLAPI void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
+RLAPI int GetScreenWidth(void); // Get current screen width
+RLAPI int GetScreenHeight(void); // Get current screen height
+
+RLAPI void ShowCursor(void); // Shows cursor
+RLAPI void HideCursor(void); // Hides cursor
+RLAPI bool IsCursorHidden(void); // Returns true if cursor is not visible
+RLAPI void EnableCursor(void); // Enables cursor
+RLAPI void DisableCursor(void); // Disables cursor
+
+RLAPI void ClearBackground(Color color); // Sets Background Color
+RLAPI void BeginDrawing(void); // Setup drawing canvas 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
+RLAPI void End2dMode(void); // Ends 2D mode custom camera usage
+RLAPI void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup)
+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
+
+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 from a 3d world space position
+RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
+
+RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
+RLAPI float GetFPS(void); // Returns current FPS
+RLAPI float GetFrameTime(void); // Returns time in seconds for one frame
+
+RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color
+RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
+RLAPI float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array
+RLAPI float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
+
+RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
+RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
+
+RLAPI void SetConfigFlags(char flags); // Setup some window configuration flags
+RLAPI void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
+
+RLAPI bool IsFileDropped(void); // Check if a file have been dropped into window
+RLAPI char **GetDroppedFiles(int *count); // Retrieve dropped files into window
+RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer
+
+RLAPI void StorageSaveValue(int position, int value); // Storage save integer value (to defined position)
+RLAPI int StorageLoadValue(int position); // Storage load integer value (from defined position)
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-bool IsKeyPressed(int key); // Detect if a key has been pressed once
-bool IsKeyDown(int key); // Detect if a key is being pressed
-bool IsKeyReleased(int key); // Detect if a key has been released once
-bool IsKeyUp(int key); // Detect if a key is NOT being pressed
-int GetKeyPressed(void); // Get latest key pressed
-void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
-
-bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
-float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
-bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
-bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
-bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
-bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
+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)
+
+RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
+RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
+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
#endif
-bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
-bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
-bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
-bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
-int GetMouseX(void); // Returns mouse position X
-int GetMouseY(void); // Returns mouse position Y
-Vector2 GetMousePosition(void); // Returns mouse position XY
-void SetMousePosition(Vector2 position); // Set mouse position XY
-int GetMouseWheelMove(void); // Returns mouse wheel movement Y
+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
-int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
-int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
-Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
+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)
#if defined(PLATFORM_ANDROID)
bool IsButtonPressed(int button); // Detect if an android physic button has been pressed
@@ -655,254 +692,262 @@ bool IsButtonReleased(int button); // Detect if an android
//------------------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: gestures)
//------------------------------------------------------------------------------------
-void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
-bool IsGestureDetected(int gesture); // Check if a gesture have been detected
-void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
-void UpdateGestures(void); // Update gestures detected (called automatically in PollInputEvents())
-
-int GetTouchPointsCount(void); // Get touch points count
-int GetGestureDetected(void); // Get latest detected gesture
-float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
-Vector2 GetGestureDragVector(void); // Get gesture drag vector
-float GetGestureDragAngle(void); // Get gesture drag angle
-Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
-float GetGesturePinchAngle(void); // Get gesture pinch angle
+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)
//------------------------------------------------------------------------------------
-void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
-void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
-void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
-
-void SetCameraPosition(Vector3 position); // Set internal camera position
-void SetCameraTarget(Vector3 target); // Set internal camera target
-void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
+RLAPI void SetCameraMode(Camera, int mode); // Set camera mode (multiple camera modes available)
+RLAPI void UpdateCamera(Camera *camera); // Update camera position for selected mode
-void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
-void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
-void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
-
-void SetCameraMoveControls(int frontKey, int backKey,
- int leftKey, int rightKey,
- int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
-void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
+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)
//------------------------------------------------------------------------------------
-void DrawPixel(int posX, int posY, Color color); // Draw a pixel
-void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
-void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
-void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
-void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
-void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
-void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
-void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
-void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
-void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
-void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
-void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
-void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
-void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
-void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
-void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
-void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
-void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
-
-bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
-bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
-bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
-Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
-bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
-bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
-bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
+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 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 DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
+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 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
+
+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 LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
-Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
-Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
-Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
-Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
-Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
-Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
-Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
-RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
-void UnloadImage(Image image); // Unload image from CPU memory (RAM)
-void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
-void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
-Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
-Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
-void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
-void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
-void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
-void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
-void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
-void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
-Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
-Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
-void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
-void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
-void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, int fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
-void ImageFlipVertical(Image *image); // Flip image vertically
-void ImageFlipHorizontal(Image *image); // Flip image horizontally
-void ImageColorTint(Image *image, Color color); // Modify image color: tint
-void ImageColorInvert(Image *image); // Modify image color: invert
-void ImageColorGrayscale(Image *image); // Modify image color: grayscale
-void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
-void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
-void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
-void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
-
-void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
-void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
-void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
-void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
-void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
+RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
+RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
+RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
+RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
+RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
+RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
+RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
+RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
+RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
+RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
+RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
+RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
+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 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)
+RLAPI void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
+RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
+
+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 GetDefaultFont(void); // Get the default SpriteFont
-SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
-void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
+RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
+RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
+RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
-void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
-void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
- int fontSize, int spacing, Color tint);
-int MeasureText(const char *text, int fontSize); // Measure string width for default font
-Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
+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);
+RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
+RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
-void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
-const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
-const char *SubText(const char *text, int position, int length); // Get a piece of a text string
+RLAPI void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
+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)
//------------------------------------------------------------------------------------
-void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
-void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
-void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
-void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
-void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
-void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
-void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
-void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
-void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
-void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
-void DrawRay(Ray ray, Color color); // Draw a ray line
-void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
-void DrawGizmo(Vector3 position); // Draw simple gizmo
-void DrawLight(Light light); // Draw light in 3D world
-void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
-void Draw3DCircle(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color); // Draw a circle in 3D world space
+RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
+RLAPI void DrawCircle3D(Vector3 center, float radius, float rotationAngle, Vector3 rotation, 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
+RLAPI void DrawLight(Light light); // Draw light in 3D world
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
-Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
-Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
-Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
-Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
-Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
-void UnloadModel(Model model); // Unload 3d model from memory
-
-Material LoadMaterial(const char *fileName); // Load material data (from file)
-Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
-Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader)
-void UnloadMaterial(Material material); // Unload material textures from VRAM
-
-void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
-void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
-void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
-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
-void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
-
-void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
-void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
-
-BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
-bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
-bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
-bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
-bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
-bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection
-bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
-Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap
- // NOTE: Return the normal vector of the impacted surface
+RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
+RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
+RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
+RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
+RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
+RLAPI void UnloadModel(Model model); // Unload 3d model from memory
+
+RLAPI Material LoadMaterial(const char *fileName); // Load material data (.MTL)
+RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
+RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader)
+RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM
+
+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
+
+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 with extended parameters and collision point detection
+RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
+
//------------------------------------------------------------------------------------
// Shaders System Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
-Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
-void UnloadShader(Shader shader); // Unload a custom shader from memory
+RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
+RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory
-Shader GetDefaultShader(void); // Get default shader
-Shader GetStandardShader(void); // Get standard shader
-Texture2D GetDefaultTexture(void); // Get default texture
+RLAPI Shader GetDefaultShader(void); // Get default shader
+RLAPI Shader GetStandardShader(void); // Get standard shader
+RLAPI Texture2D GetDefaultTexture(void); // Get default texture
-int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
-void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
-void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
-void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
+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)
-void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
-void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
+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)
-void BeginShaderMode(Shader shader); // Begin custom shader drawing
-void EndShaderMode(void); // End custom shader drawing (use default shader)
-void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
-void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
+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)
-Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
-void DestroyLight(Light light); // Destroy a light and take it out of the list
+RLAPI Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
+RLAPI void DestroyLight(Light light); // Destroy a light and take it out of the list
//------------------------------------------------------------------------------------
// VR experience Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
-void InitVrDevice(int vdDevice); // Init VR device
-void CloseVrDevice(void); // Close VR device
-void UpdateVrTracking(void); // Update VR tracking (position and orientation)
-void BeginVrDrawing(void); // Begin VR drawing configuration
-void EndVrDrawing(void); // End VR drawing process (and desktop mirror)
-bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
-void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
+RLAPI void InitVrDevice(int vdDevice); // Init VR device
+RLAPI void CloseVrDevice(void); // Close VR device
+RLAPI bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
+RLAPI void UpdateVrTracking(void); // Update VR tracking (position and orientation)
+RLAPI void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
-void InitAudioDevice(void); // Initialize audio device and context
-void CloseAudioDevice(void); // Close the audio device and context (and music stream)
-bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet
-
-Sound LoadSound(char *fileName); // Load sound to memory
-Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
-Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
-void UnloadSound(Sound sound); // Unload sound
-void PlaySound(Sound sound); // Play a sound
-void PauseSound(Sound sound); // Pause a sound
-void StopSound(Sound sound); // Stop playing a sound
-bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
-void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
-void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
-
-int PlayMusicStream(int index, char *fileName); // Start music playing (open stream)
-void UpdateMusicStream(int index); // Updates buffers for music streaming
-void StopMusicStream(int index); // Stop music playing (close stream)
-void PauseMusicStream(int index); // Pause music playing
-void ResumeMusicStream(int index); // Resume playing paused music
-bool IsMusicPlaying(int index); // Check if music is playing
-void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
-void SetMusicPitch(int index, float pitch); // Set pitch for a music (1.0 is base level)
-float GetMusicTimeLength(int index); // Get current music time length (in seconds)
-float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
-int GetMusicStreamCount(void); // Get number of streams loaded
+RLAPI void InitAudioDevice(void); // Initialize audio device and context
+RLAPI void CloseAudioDevice(void); // Close the audio device and context (and music stream)
+RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
+
+RLAPI Wave LoadWave(const char *fileName); // Load wave data from file into RAM
+RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit)
+RLAPI Sound LoadSound(const char *fileName); // Load sound to memory
+RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
+RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
+RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data
+RLAPI void UnloadWave(Wave wave);
+RLAPI void UnloadSound(Sound sound); // Unload sound
+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
+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 (open stream)
+RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming
+RLAPI void StopMusicStream(Music music); // Stop music playing (close stream)
+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 float GetMusicTimeLength(Music music); // Get music time length (in seconds)
+RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
+
+RLAPI AudioStream InitAudioStream(unsigned int sampleRate,
+ unsigned int sampleSize,
+ unsigned int channels); // Init audio stream (to stream audio pcm data)
+RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // 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
}
diff --git a/src/rlgl.c b/src/rlgl.c
index 6477efaa..244de52c 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -337,6 +337,8 @@ static int screenHeight; // Default framebuffer height
// Lighting data
static Light lights[MAX_LIGHTS]; // Lights pool
static int lightsCount = 0; // Enabled lights counter
+static int lightsLocs[MAX_LIGHTS][8]; // Lights location points in shader: 8 possible points per light:
+ // enabled, type, position, target, radius, diffuse, intensity, coneAngle
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
@@ -362,9 +364,10 @@ static void SetStereoConfig(VrDeviceInfo info);
// Set internal projection and modelview matrix depending on eyes tracking data
static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView);
-static void SetShaderLights(Shader shader); // Sets shader uniform values for lights array
+static void GetShaderLightsLocations(Shader shader); // Get shader locations for lights (up to MAX_LIGHTS)
+static void SetShaderLightsValues(Shader shader); // Set shader uniform values for lights
-static char *ReadTextFile(const char *fileName); // Read chars array from text file
+static char *ReadTextFile(const char *fileName); // Read chars array from text file
#endif
#if defined(RLGL_OCULUS_SUPPORT)
@@ -415,14 +418,14 @@ void rlMatrixMode(int mode)
}
}
-void rlFrustum(double left, double right, double bottom, double top, double near, double far)
+void rlFrustum(double left, double right, double bottom, double top, double zNear, double zFar)
{
- glFrustum(left, right, bottom, top, near, far);
+ glFrustum(left, right, bottom, top, zNear, zFar);
}
-void rlOrtho(double left, double right, double bottom, double top, double near, double far)
+void rlOrtho(double left, double right, double bottom, double top, double zNear, double zFar)
{
- glOrtho(left, right, bottom, top, near, far);
+ glOrtho(left, right, bottom, top, zNear, zFar);
}
void rlPushMatrix(void) { glPushMatrix(); }
@@ -705,7 +708,7 @@ void rlVertex3f(float x, float y, float z)
case RL_LINES:
{
// Verify that MAX_LINES_BATCH limit not reached
- if (lines.vCounter / 2 < MAX_LINES_BATCH)
+ if (lines.vCounter/2 < MAX_LINES_BATCH)
{
lines.vertices[3*lines.vCounter] = x;
lines.vertices[3*lines.vCounter + 1] = y;
@@ -719,7 +722,7 @@ void rlVertex3f(float x, float y, float z)
case RL_TRIANGLES:
{
// Verify that MAX_TRIANGLES_BATCH limit not reached
- if (triangles.vCounter / 3 < MAX_TRIANGLES_BATCH)
+ if (triangles.vCounter/3 < MAX_TRIANGLES_BATCH)
{
triangles.vertices[3*triangles.vCounter] = x;
triangles.vertices[3*triangles.vCounter + 1] = y;
@@ -733,7 +736,7 @@ void rlVertex3f(float x, float y, float z)
case RL_QUADS:
{
// Verify that MAX_QUADS_BATCH limit not reached
- if (quads.vCounter / 4 < MAX_QUADS_BATCH)
+ if (quads.vCounter/4 < MAX_QUADS_BATCH)
{
quads.vertices[3*quads.vCounter] = x;
quads.vertices[3*quads.vCounter + 1] = y;
@@ -1056,8 +1059,13 @@ void rlglInit(int width, int height)
// We get a list of available extensions and we check for some of them (compressed textures)
// NOTE: We don't need to check again supported extensions but we do (GLAD already dealt with that)
glGetIntegerv(GL_NUM_EXTENSIONS, &numExt);
- const char *extList[numExt];
+#ifdef _MSC_VER
+ const char **extList = malloc(sizeof(const char *)*numExt);
+#else
+ const char *extList[numExt];
+#endif
+
for (int i = 0; i < numExt; i++) extList[i] = (char *)glGetStringi(GL_EXTENSIONS, i);
#elif defined(GRAPHICS_API_OPENGL_ES2)
@@ -1137,6 +1145,10 @@ void rlglInit(int width, int height)
if (strcmp(extList[i], (const char *)"GL_KHR_texture_compression_astc_hdr") == 0) texCompASTCSupported = true;
}
+#ifdef _MSC_VER
+ free(extList);
+#endif
+
#if defined(GRAPHICS_API_OPENGL_ES2)
if (vaoSupported) TraceLog(INFO, "[EXTENSION] VAO extension detected, VAO functions initialized successfully");
else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported");
@@ -1275,14 +1287,20 @@ void rlglLoadExtensions(void *loader)
{
#if defined(GRAPHICS_API_OPENGL_21) || defined(GRAPHICS_API_OPENGL_33)
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
- if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
- else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
+ #ifndef __APPLE__
+ if (!gladLoadGLLoader((GLADloadproc)loader)) TraceLog(WARNING, "GLAD: Cannot load OpenGL extensions");
+ else TraceLog(INFO, "GLAD: OpenGL extensions loaded successfully");
+ #endif
#if defined(GRAPHICS_API_OPENGL_21)
- if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported");
+ #ifndef __APPLE__
+ if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported");
+ #endif
#elif defined(GRAPHICS_API_OPENGL_33)
- if(GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported");
- else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
+ #ifndef __APPLE__
+ if(GLAD_GL_VERSION_3_3) TraceLog(INFO, "OpenGL 3.3 Core profile supported");
+ else TraceLog(ERROR, "OpenGL 3.3 Core profile not supported");
+ #endif
#endif
// With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
@@ -1924,9 +1942,14 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
glUseProgram(material.shader.id);
// Upload to shader material.colDiffuse
- float vColorDiffuse[4] = { (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255 };
- glUniform4fv(material.shader.tintColorLoc, 1, vColorDiffuse);
+ glUniform4f(material.shader.colDiffuseLoc, (float)material.colDiffuse.r/255, (float)material.colDiffuse.g/255, (float)material.colDiffuse.b/255, (float)material.colDiffuse.a/255);
+
+ // Upload to shader material.colAmbient (if available)
+ if (material.shader.colAmbientLoc != -1) glUniform4f(material.shader.colAmbientLoc, (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255);
+ // Upload to shader material.colSpecular (if available)
+ if (material.shader.colSpecularLoc != -1) glUniform4f(material.shader.colSpecularLoc, (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255);
+
// At this point the modelview matrix just contains the view matrix (camera)
// That's because Begin3dMode() sets it an no model-drawing function modifies it, all use rlPushMatrix() and rlPopMatrix()
Matrix matView = modelview; // View matrix (camera)
@@ -1935,32 +1958,35 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
// Calculate model-view matrix combining matModel and matView
Matrix matModelView = MatrixMultiply(transform, matView); // Transform to camera-space coordinates
- // Check if using standard shader to get location points
- // NOTE: standard shader specific locations are got at render time to keep Shader struct as simple as possible (with just default shader locations)
- if (material.shader.id == standardShader.id)
+ // If not using default shader, we check for some additional location points
+ // NOTE: This method is quite inefficient... it's a temporal solution while looking for a better one
+ if (material.shader.id != defaultShader.id)
{
- // Transpose and inverse model transformations matrix for fragment normal calculations
- Matrix transInvTransform = transform;
- MatrixTranspose(&transInvTransform);
- MatrixInvert(&transInvTransform);
-
- // Send model transformations matrix to shader
- glUniformMatrix4fv(glGetUniformLocation(material.shader.id, "modelMatrix"), 1, false, MatrixToFloat(transInvTransform));
-
- // Send view transformation matrix to shader. View matrix 8, 9 and 10 are view direction vector axis values (target - position)
- glUniform3f(glGetUniformLocation(material.shader.id, "viewDir"), matView.m8, matView.m9, matView.m10);
-
- // Setup shader uniforms for lights
- SetShaderLights(material.shader);
-
- // Upload to shader material.colAmbient
- glUniform4f(glGetUniformLocation(material.shader.id, "colAmbient"), (float)material.colAmbient.r/255, (float)material.colAmbient.g/255, (float)material.colAmbient.b/255, (float)material.colAmbient.a/255);
-
- // Upload to shader material.colSpecular
- glUniform4f(glGetUniformLocation(material.shader.id, "colSpecular"), (float)material.colSpecular.r/255, (float)material.colSpecular.g/255, (float)material.colSpecular.b/255, (float)material.colSpecular.a/255);
-
- // Upload to shader glossiness
- glUniform1f(glGetUniformLocation(material.shader.id, "glossiness"), material.glossiness);
+ // Check if model matrix is located in shader and upload value
+ int modelMatrixLoc = glGetUniformLocation(material.shader.id, "modelMatrix");
+ if (modelMatrixLoc != -1)
+ {
+ // Transpose and inverse model transformations matrix for fragment normal calculations
+ Matrix transInvTransform = transform;
+ MatrixTranspose(&transInvTransform);
+ MatrixInvert(&transInvTransform);
+
+ // Send model transformations matrix to shader
+ glUniformMatrix4fv(modelMatrixLoc, 1, false, MatrixToFloat(transInvTransform));
+ }
+
+ // Check if view direction is located in shader and upload value
+ // NOTE: View matrix values m8, m9 and m10 are view direction vector axis (target - position)
+ int viewDirLoc = glGetUniformLocation(material.shader.id, "viewDir");
+ if (viewDirLoc != -1) glUniform3f(viewDirLoc, matView.m8, matView.m9, matView.m10);
+
+ // Check if glossiness is located in shader and upload value
+ int glossinessLoc = glGetUniformLocation(material.shader.id, "glossiness");
+ if (glossinessLoc != -1) glUniform1f(glossinessLoc, material.glossiness);
+
+ // Set shader lights values for enabled lights
+ // NOTE: Lights array location points are obtained on shader loading (if available)
+ if (lightsCount > 0) SetShaderLightsValues(material.shader);
}
// Set shader textures (diffuse, normal, specular)
@@ -2544,11 +2570,13 @@ void DestroyLight(Light light)
{
if (light != NULL)
{
+ int lightId = light->id;
+
// Free dynamic memory allocation
- free(lights[light->id]);
-
+ free(lights[lightId]);
+
// Remove *obj from the pointers array
- for (int i = light->id; i < lightsCount; i++)
+ for (int i = lightId; i < lightsCount; i++)
{
// Resort all the following pointers of the array
if ((i + 1) < lightsCount)
@@ -2556,7 +2584,6 @@ void DestroyLight(Light light)
lights[i] = lights[i + 1];
lights[i]->id = lights[i + 1]->id;
}
- else free(lights[i]);
}
// Decrease enabled physic objects count
@@ -2885,11 +2912,18 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
+#ifdef _MSC_VER
+ char *log = malloc(maxLength);
+#else
char log[maxLength];
-
+#endif
glGetShaderInfoLog(vertexShader, maxLength, &length, log);
TraceLog(INFO, "%s", log);
+
+#ifdef _MSC_VER
+ free(log);
+#endif
}
else TraceLog(INFO, "[VSHDR ID %i] Vertex shader compiled successfully", vertexShader);
@@ -2906,11 +2940,18 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
+#ifdef _MSC_VER
+ char *log = malloc(maxLength);
+#else
char log[maxLength];
-
+#endif
glGetShaderInfoLog(fragmentShader, maxLength, &length, log);
TraceLog(INFO, "%s", log);
+
+#ifdef _MSC_VER
+ free(log);
+#endif
}
else TraceLog(INFO, "[FSHDR ID %i] Fragment shader compiled successfully", fragmentShader);
@@ -2944,12 +2985,18 @@ static unsigned int LoadShaderProgram(const char *vShaderStr, const char *fShade
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
+#ifdef _MSC_VER
+ char *log = malloc(maxLength);
+#else
char log[maxLength];
-
+#endif
glGetProgramInfoLog(program, maxLength, &length, log);
TraceLog(INFO, "%s", log);
-
+
+#ifdef _MSC_VER
+ free(log);
+#endif
glDeleteProgram(program);
program = 0;
@@ -3064,7 +3111,7 @@ static Shader LoadStandardShader(void)
shader = GetDefaultShader();
}
#else
- shader = defaultShader;
+ shader = GetDefaultShader();
TraceLog(WARNING, "[SHDR ID %i] Standard shader not available, using default shader", shader.id);
#endif
@@ -3076,12 +3123,12 @@ static Shader LoadStandardShader(void)
static void LoadDefaultShaderLocations(Shader *shader)
{
// NOTE: Default shader attrib locations have been fixed before linking:
- // vertex position location = 0
- // vertex texcoord location = 1
- // vertex normal location = 2
- // vertex color location = 3
- // vertex tangent location = 4
- // vertex texcoord2 location = 5
+ // vertex position location = 0
+ // vertex texcoord location = 1
+ // vertex normal location = 2
+ // vertex color location = 3
+ // vertex tangent location = 4
+ // vertex texcoord2 location = 5
// Get handles to GLSL input attibute locations
shader->vertexLoc = glGetAttribLocation(shader->id, DEFAULT_ATTRIB_POSITION_NAME);
@@ -3095,10 +3142,18 @@ static void LoadDefaultShaderLocations(Shader *shader)
shader->mvpLoc = glGetUniformLocation(shader->id, "mvpMatrix");
// Get handles to GLSL uniform locations (fragment shader)
- shader->tintColorLoc = glGetUniformLocation(shader->id, "colDiffuse");
+ shader->colDiffuseLoc = glGetUniformLocation(shader->id, "colDiffuse");
+ shader->colAmbientLoc = glGetUniformLocation(shader->id, "colAmbient");
+ shader->colSpecularLoc = glGetUniformLocation(shader->id, "colSpecular");
+
shader->mapTexture0Loc = glGetUniformLocation(shader->id, "texture0");
shader->mapTexture1Loc = glGetUniformLocation(shader->id, "texture1");
shader->mapTexture2Loc = glGetUniformLocation(shader->id, "texture2");
+
+ // TODO: Try to find all expected/recognized shader locations (predefined names, must be documented)
+
+ // Try to get lights location points (if available)
+ GetShaderLightsLocations(*shader);
}
// Unload default shader
@@ -3389,7 +3444,7 @@ static void DrawDefaultBuffers(int eyesCount)
Matrix matMVP = MatrixMultiply(modelview, projection);
glUniformMatrix4fv(currentShader.mvpLoc, 1, false, MatrixToFloat(matMVP));
- glUniform4f(currentShader.tintColorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
+ glUniform4f(currentShader.colDiffuseLoc, 1.0f, 1.0f, 1.0f, 1.0f);
glUniform1i(currentShader.mapTexture0Loc, 0);
// NOTE: Additional map textures not considered for default buffers drawing
@@ -3487,7 +3542,7 @@ static void DrawDefaultBuffers(int eyesCount)
for (int i = 0; i < drawsCounter; i++)
{
quadsCount = draws[i].vertexCount/4;
- numIndicesToProcess = quadsCount*6; // Get number of Quads * 6 index by Quad
+ numIndicesToProcess = quadsCount*6; // Get number of Quads*6 index by Quad
//TraceLog(DEBUG, "Quads to render: %i - Vertex Count: %i", quadsCount, draws[i].vertexCount);
@@ -3584,82 +3639,100 @@ static void UnloadDefaultBuffers(void)
free(quads.indices);
}
-// Setup shader uniform values for lights array
-// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0f
-static void SetShaderLights(Shader shader)
+// Get shader locations for lights (up to MAX_LIGHTS)
+static void GetShaderLightsLocations(Shader shader)
{
- int locPoint = -1;
- char locName[32] = "lights[x].position\0";
-
+ char locName[32] = "lights[x].\0";
+ char locNameUpdated[64];
+
for (int i = 0; i < MAX_LIGHTS; i++)
{
locName[7] = '0' + i;
+
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "enabled\0");
+ lightsLocs[i][0] = glGetUniformLocation(shader.id, locNameUpdated);
+
+ locNameUpdated[0] = '\0';
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "type\0");
+ lightsLocs[i][1] = glGetUniformLocation(shader.id, locNameUpdated);
+
+ locNameUpdated[0] = '\0';
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "position\0");
+ lightsLocs[i][2] = glGetUniformLocation(shader.id, locNameUpdated);
+
+ locNameUpdated[0] = '\0';
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "direction\0");
+ lightsLocs[i][3] = glGetUniformLocation(shader.id, locNameUpdated);
+
+ locNameUpdated[0] = '\0';
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "radius\0");
+ lightsLocs[i][4] = glGetUniformLocation(shader.id, locNameUpdated);
+
+ locNameUpdated[0] = '\0';
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "diffuse\0");
+ lightsLocs[i][5] = glGetUniformLocation(shader.id, locNameUpdated);
+
+ locNameUpdated[0] = '\0';
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "intensity\0");
+ lightsLocs[i][6] = glGetUniformLocation(shader.id, locNameUpdated);
+
+ locNameUpdated[0] = '\0';
+ strcpy(locNameUpdated, locName);
+ strcat(locNameUpdated, "coneAngle\0");
+ lightsLocs[i][7] = glGetUniformLocation(shader.id, locNameUpdated);
+ }
+}
- if (lights[i] != NULL) // Only upload registered lights data
+// Set shader uniform values for lights
+// NOTE: It would be far easier with shader UBOs but are not supported on OpenGL ES 2.0
+static void SetShaderLightsValues(Shader shader)
+{
+ for (int i = 0; i < MAX_LIGHTS; i++)
+ {
+ if (i < lightsCount)
{
- memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform1i(locPoint, lights[i]->enabled);
-
- memcpy(&locName[10], "type\0", strlen("type\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform1i(locPoint, lights[i]->type);
-
- memcpy(&locName[10], "diffuse\0", strlen("diffuse\0") + 2);
- locPoint = glGetUniformLocation(shader.id, locName);
- glUniform4f(locPoint, (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255);
-
- memcpy(&locName[10], "intensity\0", strlen("intensity\0"));
- locPoint = glGetUniformLocation(shader.id, locName);
- glUniform1f(locPoint, lights[i]->intensity);
+ glUniform1i(lightsLocs[i][0], lights[i]->enabled);
+
+ glUniform1i(lightsLocs[i][1], lights[i]->type);
+ glUniform4f(lightsLocs[i][5], (float)lights[i]->diffuse.r/255, (float)lights[i]->diffuse.g/255, (float)lights[i]->diffuse.b/255, (float)lights[i]->diffuse.a/255);
+ glUniform1f(lightsLocs[i][6], lights[i]->intensity);
switch (lights[i]->type)
{
case LIGHT_POINT:
{
- memcpy(&locName[10], "position\0", strlen("position\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
-
- memcpy(&locName[10], "radius\0", strlen("radius\0") + 2);
- locPoint = GetShaderLocation(shader, locName);
- glUniform1f(locPoint, lights[i]->radius);
+ glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
+ glUniform1f(lightsLocs[i][4], lights[i]->radius);
} break;
case LIGHT_DIRECTIONAL:
{
- memcpy(&locName[10], "direction\0", strlen("direction\0") + 2);
- locPoint = GetShaderLocation(shader, locName);
- Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z };
+ Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position);
VectorNormalize(&direction);
- glUniform3f(locPoint, direction.x, direction.y, direction.z);
+ glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z);
} break;
case LIGHT_SPOT:
{
- memcpy(&locName[10], "position\0", strlen("position\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform3f(locPoint, lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
-
- memcpy(&locName[10], "direction\0", strlen("direction\0") + 2);
- locPoint = GetShaderLocation(shader, locName);
+ glUniform3f(lightsLocs[i][2], lights[i]->position.x, lights[i]->position.y, lights[i]->position.z);
- Vector3 direction = { lights[i]->target.x - lights[i]->position.x, lights[i]->target.y - lights[i]->position.y, lights[i]->target.z - lights[i]->position.z };
+ Vector3 direction = VectorSubtract(lights[i]->target, lights[i]->position);
VectorNormalize(&direction);
- glUniform3f(locPoint, direction.x, direction.y, direction.z);
+ glUniform3f(lightsLocs[i][3], direction.x, direction.y, direction.z);
- memcpy(&locName[10], "coneAngle\0", strlen("coneAngle\0"));
- locPoint = GetShaderLocation(shader, locName);
- glUniform1f(locPoint, lights[i]->coneAngle);
+ glUniform1f(lightsLocs[i][7], lights[i]->coneAngle);
} break;
default: break;
}
-
- // TODO: Pass to the shader any other required data from LightData struct
}
- else // Not enabled lights
+ else
{
- memcpy(&locName[10], "enabled\0", strlen("enabled\0") + 1);
- locPoint = GetShaderLocation(shader, locName);
- glUniform1i(locPoint, 0);
+ glUniform1i(lightsLocs[i][0], 0); // Light disabled
}
}
}
diff --git a/src/rlgl.h b/src/rlgl.h
index 425871a9..5fc9f8b9 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -107,7 +107,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
// byte type
typedef unsigned char byte;
-
+
// Color type, RGBA (32bit)
typedef struct Color {
unsigned char r;
@@ -117,7 +117,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
} Color;
// Texture formats (support depends on OpenGL version)
- typedef enum {
+ typedef enum {
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
UNCOMPRESSED_GRAY_ALPHA,
UNCOMPRESSED_R5G6B5, // 16 bpp
@@ -157,7 +157,7 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Shader type (generic shader)
typedef struct Shader {
unsigned int id; // Shader program id
-
+
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
@@ -168,8 +168,10 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
- int tintColorLoc; // Color uniform location point (fragment shader)
-
+ int colDiffuseLoc; // Color uniform location point (fragment shader)
+ int colAmbientLoc; // Ambient color uniform location point (fragment shader)
+ int colSpecularLoc; // Specular color uniform location point (fragment shader)
+
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
@@ -185,14 +187,14 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
int mipmaps; // Mipmap levels, 1 by default
int format; // Data format (TextureFormat)
} Texture2D;
-
+
// RenderTexture2D type, for texture rendering
typedef struct RenderTexture2D {
unsigned int id; // Render texture (fbo) id
Texture2D texture; // Color buffer attachment texture
Texture2D depth; // Depth buffer attachment texture
} RenderTexture2D;
-
+
// Material type
typedef struct Material {
Shader shader; // Standard shader (supports 3 map types: diffuse, normal, specular)
@@ -204,10 +206,10 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
-
+
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material;
-
+
// Camera type, defines a camera position/orientation in 3d space
typedef struct Camera {
Vector3 position; // Camera position
@@ -225,22 +227,22 @@ typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
Vector3 position; // Light position
Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Light attenuation radius light intensity reduced with distance (world distance)
-
+
Color diffuse; // Light diffuse color
float intensity; // Light intensity level
-
+
float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light;
-
+
// Light types
typedef enum { LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT } LightType;
// Color blending modes (pre-defined)
typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
-
+
// TraceLog message types
typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
-
+
// VR Head Mounted Display devices
typedef enum {
HMD_DEFAULT_DEVICE = 0,
@@ -332,6 +334,10 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world
unsigned char *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
void *rlglReadTexturePixels(Texture2D texture); // Read texture pixel data
+// VR functions exposed to core module but not to raylib users
+void BeginVrDrawing(void); // Begin VR drawing configuration
+void EndVrDrawing(void); // End VR drawing process (and desktop mirror)
+
// NOTE: There is a set of shader related functions that are available to end user,
// to avoid creating function wrappers through core module, they have been directly declared in raylib.h
@@ -368,10 +374,8 @@ float *MatrixToFloat(Matrix mat);
void InitVrDevice(int vrDevice); // Init VR device
void CloseVrDevice(void); // Close VR device
-void UpdateVrTracking(void); // Update VR tracking (position and orientation)
-void BeginVrDrawing(void); // Begin VR drawing configuration
-void EndVrDrawing(void); // End VR drawing process (and desktop mirror)
bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
+void UpdateVrTracking(void); // Update VR tracking (position and orientation)
void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
// Oculus Rift API for direct access the device (no simulator)
diff --git a/src/rlua.h b/src/rlua.h
new file mode 100644
index 00000000..1c8c7b38
--- /dev/null
+++ b/src/rlua.h
@@ -0,0 +1,4206 @@
+/**********************************************************************************************
+*
+* rlua - raylib Lua bindings
+*
+* NOTE 01:
+* The following types:
+* Color, Vector2, Vector3, Rectangle, Ray, Camera, Camera2D
+* are treated as objects with named fields, same as in C.
+*
+* Lua defines utility functions for creating those objects.
+* Usage:
+* local cl = Color(255,255,255,255)
+* local rec = Rectangle(10, 10, 100, 100)
+* local ray = Ray(Vector3(20, 20, 20), Vector3(50, 50, 50))
+* local x2 = rec.x + rec.width
+*
+* The following types:
+* Image, Texture2D, RenderTexture2D, SpriteFont
+* are immutable, and you can only read their non-pointer arguments (e.g. sprfnt.size).
+*
+* All other object types are opaque, that is, you cannot access or
+* change their fields directly.
+*
+* Remember that ALL raylib types have REFERENCE SEMANTICS in Lua.
+* There is currently no way to create a copy of an opaque object.
+*
+* NOTE 02:
+* Some raylib functions take a pointer to an array, and the size of that array.
+* The equivalent Lua functions take only an array table of the specified type UNLESS
+* it's a pointer to a large char array (e.g. for images), then it takes (and potentially returns)
+* a Lua string (without the size argument, as Lua strings are sized by default).
+*
+* NOTE 03:
+* Some raylib functions take pointers to objects to modify (e.g. ImageToPOT, etc.)
+* In Lua, these functions take values and return a new changed value, instead.
+* So, in C:
+* ImageToPOT(&img, BLACK);
+* In Lua becomes:
+* img = ImageToPOT(img, BLACK)
+*
+* Remember that functions can return multiple values, so:
+* UpdateCameraPlayer(&cam, &playerPos);
+* Vector3 vec = ResolveCollisionCubicmap(img, mapPos, &playerPos, 5.0);
+* becomes:
+* cam, playerPos = UpdateCameraPlayer(cam, playerPos)
+* vec, playerPos = ResolveCollisionCubicmap(img, mapPos, playerPos, 5)
+*
+* This is to preserve value semantics of raylib objects.
+*
+*
+* This Lua binding for raylib was originally created by Ghassan Al-Mashareqa ([email protected])
+* for raylib 1.3 and later on reviewed and updated to raylib 1.6 by Ramon Santamaria.
+*
+* Copyright (c) 2015-2016 Ghassan Al-Mashareqa and 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.
+*
+**********************************************************************************************/
+
+#pragma once
+
+#include "raylib.h"
+
+#define RLUA_STATIC
+#ifdef RLUA_STATIC
+ #define RLUADEF static // Functions just visible to module including this file
+#else
+ #ifdef __cplusplus
+ #define RLUADEF extern "C" // Functions visible from other files (no name mangling of functions in C++)
+ #else
+ #define RLUADEF extern // Functions visible from other files
+ #endif
+#endif
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+// ...
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+RLUADEF void InitLuaDevice(void); // Initialize Lua system
+RLUADEF void ExecuteLuaCode(const char *code); // Execute raylib Lua code
+RLUADEF void ExecuteLuaFile(const char *filename); // Execute raylib Lua script
+RLUADEF void CloseLuaDevice(void); // De-initialize Lua system
+
+/***********************************************************************************
+*
+* RLUA IMPLEMENTATION
+*
+************************************************************************************/
+
+#if defined(RLUA_IMPLEMENTATION)
+
+#include "raylib.h"
+#include "utils.h"
+#include "raymath.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+#define LuaPush_Image(L, img) LuaPushOpaqueTypeWithMetatable(L, img, Image)
+#define LuaPush_Texture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, Texture2D)
+#define LuaPush_RenderTexture2D(L, tex) LuaPushOpaqueTypeWithMetatable(L, tex, RenderTexture2D)
+#define LuaPush_SpriteFont(L, sf) LuaPushOpaqueTypeWithMetatable(L, sf, SpriteFont)
+#define LuaPush_Mesh(L, vd) LuaPushOpaqueType(L, vd)
+#define LuaPush_Shader(L, s) LuaPushOpaqueType(L, s)
+#define LuaPush_Light(L, light) LuaPushOpaqueTypeWithMetatable(L, light, Light)
+#define LuaPush_Sound(L, snd) LuaPushOpaqueType(L, snd)
+#define LuaPush_Wave(L, wav) LuaPushOpaqueType(L, wav)
+#define LuaPush_Music(L, mus) LuaPushOpaqueType(L, mus)
+#define LuaPush_AudioStream(L, aud) LuaPushOpaqueType(L, aud)
+
+#define LuaGetArgument_string luaL_checkstring
+#define LuaGetArgument_int (int)luaL_checkinteger
+#define LuaGetArgument_unsigned (unsigned)luaL_checkinteger
+#define LuaGetArgument_char (char)luaL_checkinteger
+#define LuaGetArgument_float (float)luaL_checknumber
+#define LuaGetArgument_double luaL_checknumber
+
+#define LuaGetArgument_Image(L, img) *(Image*)LuaGetArgumentOpaqueTypeWithMetatable(L, img, "Image")
+#define LuaGetArgument_Texture2D(L, tex) *(Texture2D*)LuaGetArgumentOpaqueTypeWithMetatable(L, tex, "Texture2D")
+#define LuaGetArgument_RenderTexture2D(L, rtex) *(RenderTexture2D*)LuaGetArgumentOpaqueTypeWithMetatable(L, rtex, "RenderTexture2D")
+#define LuaGetArgument_SpriteFont(L, sf) *(SpriteFont*)LuaGetArgumentOpaqueTypeWithMetatable(L, sf, "SpriteFont")
+#define LuaGetArgument_Mesh(L, vd) *(Mesh*)LuaGetArgumentOpaqueType(L, vd)
+#define LuaGetArgument_Shader(L, s) *(Shader*)LuaGetArgumentOpaqueType(L, s)
+#define LuaGetArgument_Light(L, light) *(Light*)LuaGetArgumentOpaqueType(L, light)
+#define LuaGetArgument_Sound(L, snd) *(Sound*)LuaGetArgumentOpaqueType(L, snd)
+#define LuaGetArgument_Wave(L, wav) *(Wave*)LuaGetArgumentOpaqueType(L, wav)
+#define LuaGetArgument_Music(L, mus) *(Music*)LuaGetArgumentOpaqueType(L, mus)
+#define LuaGetArgument_AudioStream(L, aud) *(AudioStream*)LuaGetArgumentOpaqueType(L, aud)
+
+#define LuaPushOpaqueType(L, str) LuaPushOpaque(L, &str, sizeof(str))
+#define LuaPushOpaqueTypeWithMetatable(L, str, meta) LuaPushOpaqueWithMetatable(L, &str, sizeof(str), #meta)
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+static lua_State* mainLuaState = 0;
+static lua_State* L = 0;
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Declaration
+//----------------------------------------------------------------------------------
+static void LuaPush_Color(lua_State* L, Color color);
+static void LuaPush_Vector2(lua_State* L, Vector2 vec);
+static void LuaPush_Vector3(lua_State* L, Vector3 vec);
+static void LuaPush_Quaternion(lua_State* L, Quaternion vec);
+static void LuaPush_Matrix(lua_State* L, Matrix *matrix);
+static void LuaPush_Rectangle(lua_State* L, Rectangle rect);
+static void LuaPush_Model(lua_State* L, Model mdl);
+static void LuaPush_Ray(lua_State* L, Ray ray);
+static void LuaPush_Camera(lua_State* L, Camera cam);
+
+static Vector2 LuaGetArgument_Vector2(lua_State* L, int index);
+static Vector3 LuaGetArgument_Vector3(lua_State* L, int index);
+static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index);
+static Color LuaGetArgument_Color(lua_State* L, int index);
+static Rectangle LuaGetArgument_Rectangle(lua_State* L, int index);
+static Camera LuaGetArgument_Camera(lua_State* L, int index);
+static Camera2D LuaGetArgument_Camera2D(lua_State* L, int index);
+static Ray LuaGetArgument_Ray(lua_State* L, int index);
+static Matrix LuaGetArgument_Matrix(lua_State* L, int index);
+static Model LuaGetArgument_Model(lua_State* L, int index);
+
+//----------------------------------------------------------------------------------
+// rlua Helper Functions
+//----------------------------------------------------------------------------------
+static void LuaStartEnum(void)
+{
+ lua_newtable(L);
+}
+
+static void LuaSetEnum(const char *name, int value)
+{
+ lua_pushinteger(L, value);
+ lua_setfield(L, -2, name);
+}
+
+static void LuaSetEnumColor(const char *name, Color color)
+{
+ LuaPush_Color(L, color);
+ lua_setfield(L, -2, name);
+}
+
+static void LuaEndEnum(const char *name)
+{
+ lua_setglobal(L, name);
+}
+
+static void LuaPushOpaque(lua_State* L, void *ptr, size_t size)
+{
+ void *ud = lua_newuserdata(L, size);
+ memcpy(ud, ptr, size);
+}
+
+static void LuaPushOpaqueWithMetatable(lua_State* L, void *ptr, size_t size, const char *metatable_name)
+{
+ void *ud = lua_newuserdata(L, size);
+ memcpy(ud, ptr, size);
+ luaL_setmetatable(L, metatable_name);
+}
+
+static void* LuaGetArgumentOpaqueType(lua_State* L, int index)
+{
+ return lua_touserdata(L, index);
+}
+
+static void* LuaGetArgumentOpaqueTypeWithMetatable(lua_State* L, int index, const char *metatable_name)
+{
+ return luaL_checkudata(L, index, metatable_name);
+}
+
+//----------------------------------------------------------------------------------
+// LuaIndex* functions
+//----------------------------------------------------------------------------------
+static int LuaIndexImage(lua_State* L)
+{
+ Image img = LuaGetArgument_Image(L, 1);
+ const char *key = luaL_checkstring(L, 2);
+ if (!strcmp(key, "width"))
+ lua_pushinteger(L, img.width);
+ else if (!strcmp(key, "height"))
+ lua_pushinteger(L, img.height);
+ else if (!strcmp(key, "mipmaps"))
+ lua_pushinteger(L, img.mipmaps);
+ else if (!strcmp(key, "format"))
+ lua_pushinteger(L, img.format);
+ else
+ return 0;
+ return 1;
+}
+
+static int LuaIndexTexture2D(lua_State* L)
+{
+ Texture2D img = LuaGetArgument_Texture2D(L, 1);
+ const char *key = luaL_checkstring(L, 2);
+ if (!strcmp(key, "width"))
+ lua_pushinteger(L, img.width);
+ else if (!strcmp(key, "height"))
+ lua_pushinteger(L, img.height);
+ else if (!strcmp(key, "mipmaps"))
+ lua_pushinteger(L, img.mipmaps);
+ else if (!strcmp(key, "format"))
+ lua_pushinteger(L, img.format);
+ else if (!strcmp(key, "id"))
+ lua_pushinteger(L, img.id);
+ else
+ return 0;
+ return 1;
+}
+
+static int LuaIndexRenderTexture2D(lua_State* L)
+{
+ RenderTexture2D img = LuaGetArgument_RenderTexture2D(L, 1);
+ const char *key = luaL_checkstring(L, 2);
+ if (!strcmp(key, "texture"))
+ LuaPush_Texture2D(L, img.texture);
+ else if (!strcmp(key, "depth"))
+ LuaPush_Texture2D(L, img.depth);
+ else
+ return 0;
+ return 1;
+}
+
+static int LuaIndexSpriteFont(lua_State* L)
+{
+ SpriteFont img = LuaGetArgument_SpriteFont(L, 1);
+ const char *key = luaL_checkstring(L, 2);
+ if (!strcmp(key, "size"))
+ lua_pushinteger(L, img.size);
+ else if (!strcmp(key, "texture"))
+ LuaPush_Texture2D(L, img.texture);
+ else if (!strcmp(key, "numChars"))
+ lua_pushinteger(L, img.numChars);
+ else
+ return 0;
+ return 1;
+}
+
+static int LuaIndexLight(lua_State* L)
+{
+ Light light = LuaGetArgument_Light(L, 1);
+ const char *key = luaL_checkstring(L, 2);
+ if (!strcmp(key, "id"))
+ lua_pushinteger(L, light->id);
+ else if (!strcmp(key, "enabled"))
+ lua_pushboolean(L, light->enabled);
+ else if (!strcmp(key, "type"))
+ lua_pushinteger(L, light->type);
+ else if (!strcmp(key, "position"))
+ LuaPush_Vector3(L, light->position);
+ else if (!strcmp(key, "target"))
+ LuaPush_Vector3(L, light->target);
+ else if (!strcmp(key, "radius"))
+ lua_pushnumber(L, light->radius);
+ else if (!strcmp(key, "diffuse"))
+ LuaPush_Color(L, light->diffuse);
+ else if (!strcmp(key, "intensity"))
+ lua_pushnumber(L, light->intensity);
+ else if (!strcmp(key, "coneAngle"))
+ lua_pushnumber(L, light->coneAngle);
+ else
+ return 0;
+ return 1;
+}
+
+static int LuaNewIndexLight(lua_State* L)
+{
+ Light light = LuaGetArgument_Light(L, 1);
+ const char *key = luaL_checkstring(L, 2);
+ if (!strcmp(key, "id"))
+ light->id = LuaGetArgument_int(L, 3);
+ else if (!strcmp(key, "enabled"))
+ light->enabled = lua_toboolean(L, 3);
+ else if (!strcmp(key, "type"))
+ light->type = LuaGetArgument_int(L, 3);
+ else if (!strcmp(key, "position"))
+ light->position = LuaGetArgument_Vector3(L, 3);
+ else if (!strcmp(key, "target"))
+ light->target = LuaGetArgument_Vector3(L, 3);
+ else if (!strcmp(key, "radius"))
+ light->radius = LuaGetArgument_float(L, 3);
+ else if (!strcmp(key, "diffuse"))
+ light->diffuse = LuaGetArgument_Color(L, 3);
+ else if (!strcmp(key, "intensity"))
+ light->intensity = LuaGetArgument_float(L, 3);
+ else if (!strcmp(key, "coneAngle"))
+ light->coneAngle = LuaGetArgument_float(L, 3);
+ return 0;
+}
+
+static void LuaBuildOpaqueMetatables(void)
+{
+ luaL_newmetatable(L, "Image");
+ lua_pushcfunction(L, &LuaIndexImage);
+ lua_setfield(L, -2, "__index");
+ lua_pop(L, 1);
+
+ luaL_newmetatable(L, "Texture2D");
+ lua_pushcfunction(L, &LuaIndexTexture2D);
+ lua_setfield(L, -2, "__index");
+ lua_pop(L, 1);
+
+ luaL_newmetatable(L, "RenderTexture2D");
+ lua_pushcfunction(L, &LuaIndexRenderTexture2D);
+ lua_setfield(L, -2, "__index");
+ lua_pop(L, 1);
+
+ luaL_newmetatable(L, "SpriteFont");
+ lua_pushcfunction(L, &LuaIndexSpriteFont);
+ lua_setfield(L, -2, "__index");
+ lua_pop(L, 1);
+
+ luaL_newmetatable(L, "Light");
+ lua_pushcfunction(L, &LuaIndexLight);
+ lua_setfield(L, -2, "__index");
+ lua_pushcfunction(L, &LuaNewIndexLight);
+ lua_setfield(L, -2, "__newindex");
+ lua_pop(L, 1);
+}
+
+//----------------------------------------------------------------------------------
+// LuaGetArgument functions
+//----------------------------------------------------------------------------------
+
+static Vector2 LuaGetArgument_Vector2(lua_State* L, int index)
+{
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector2");
+ float x = (float)lua_tonumber(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector2");
+ float y = (float)lua_tonumber(L, -1);
+ lua_pop(L, 2);
+ return (Vector2) { x, y };
+}
+
+static Vector3 LuaGetArgument_Vector3(lua_State* L, int index)
+{
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Vector3");
+ float x = (float)lua_tonumber(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Vector3");
+ float y = (float)lua_tonumber(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Vector3");
+ float z = (float)lua_tonumber(L, -1);
+ lua_pop(L, 3);
+ return (Vector3) { x, y, z };
+}
+
+static Quaternion LuaGetArgument_Quaternion(lua_State* L, int index)
+{
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Quaternion");
+ float x = (float)lua_tonumber(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Quaternion");
+ float y = (float)lua_tonumber(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "z") == LUA_TNUMBER, index, "Expected Quaternion");
+ float z = (float)lua_tonumber(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "w") == LUA_TNUMBER, index, "Expected Quaternion");
+ float w = (float)lua_tonumber(L, -1);
+ lua_pop(L, 4);
+ return (Quaternion) { x, y, z, w };
+}
+
+static Color LuaGetArgument_Color(lua_State* L, int index)
+{
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "r") == LUA_TNUMBER, index, "Expected Color");
+ unsigned char r = (unsigned char)lua_tointeger(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "g") == LUA_TNUMBER, index, "Expected Color");
+ unsigned char g = (unsigned char)lua_tointeger(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "b") == LUA_TNUMBER, index, "Expected Color");
+ unsigned char b = (unsigned char)lua_tointeger(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "a") == LUA_TNUMBER, index, "Expected Color");
+ unsigned char a = (unsigned char)lua_tointeger(L, -1);
+ lua_pop(L, 4);
+ return (Color) { r, g, b, a };
+}
+
+static Rectangle LuaGetArgument_Rectangle(lua_State* L, int index)
+{
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "x") == LUA_TNUMBER, index, "Expected Rectangle");
+ int x = (int)lua_tointeger(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "y") == LUA_TNUMBER, index, "Expected Rectangle");
+ int y = (int)lua_tointeger(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "width") == LUA_TNUMBER, index, "Expected Rectangle");
+ int w = (int)lua_tointeger(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "height") == LUA_TNUMBER, index, "Expected Rectangle");
+ int h = (int)lua_tointeger(L, -1);
+ lua_pop(L, 4);
+ return (Rectangle) { x, y, w, h };
+}
+
+static Camera LuaGetArgument_Camera(lua_State* L, int index)
+{
+ Camera result;
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TTABLE, index, "Expected Camera");
+ result.position = LuaGetArgument_Vector3(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TTABLE, index, "Expected Camera");
+ result.target = LuaGetArgument_Vector3(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "up") == LUA_TTABLE, index, "Expected Camera");
+ result.up = LuaGetArgument_Vector3(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "fovy") == LUA_TNUMBER, index, "Expected Camera");
+ result.fovy = LuaGetArgument_float(L, -1);
+ lua_pop(L, 4);
+ return result;
+}
+
+static Camera2D LuaGetArgument_Camera2D(lua_State* L, int index)
+{
+ Camera2D result;
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "offset") == LUA_TTABLE, index, "Expected Camera2D");
+ result.offset = LuaGetArgument_Vector2(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "target") == LUA_TTABLE, index, "Expected Camera2D");
+ result.target = LuaGetArgument_Vector2(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "rotation") == LUA_TNUMBER, index, "Expected Camera2D");
+ result.rotation = LuaGetArgument_float(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "zoom") == LUA_TNUMBER, index, "Expected Camera2D");
+ result.zoom = LuaGetArgument_float(L, -1);
+ lua_pop(L, 4);
+ return result;
+}
+
+static BoundingBox LuaGetArgument_BoundingBox(lua_State* L, int index)
+{
+ BoundingBox result;
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "min") == LUA_TTABLE, index, "Expected BoundingBox");
+ result.min = LuaGetArgument_Vector3(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "max") == LUA_TTABLE, index, "Expected BoundingBox");
+ result.max = LuaGetArgument_Vector3(L, -1);
+ lua_pop(L, 2);
+ return result;
+}
+
+static Ray LuaGetArgument_Ray(lua_State* L, int index)
+{
+ Ray result;
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "position") == LUA_TTABLE, index, "Expected Ray");
+ result.position = LuaGetArgument_Vector3(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "direction") == LUA_TTABLE, index, "Expected Ray");
+ result.direction = LuaGetArgument_Vector3(L, -1);
+ lua_pop(L, 2);
+ return result;
+}
+
+static Matrix LuaGetArgument_Matrix(lua_State* L, int index)
+{
+ Matrix result = { 0 };
+ float* ptr = &result.m0;
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+
+ for (int i = 0; i < 16; i++)
+ {
+ lua_geti(L, index, i+1);
+ ptr[i] = luaL_checknumber(L, -1);
+ }
+ lua_pop(L, 16);
+ return result;
+}
+
+static Material LuaGetArgument_Material(lua_State* L, int index)
+{
+ Material result;
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "shader") == LUA_TUSERDATA, index, "Expected Material");
+ result.shader = LuaGetArgument_Shader(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "texDiffuse") == LUA_TUSERDATA, index, "Expected Material");
+ result.texDiffuse = LuaGetArgument_Texture2D(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "texNormal") == LUA_TUSERDATA, index, "Expected Material");
+ result.texNormal = LuaGetArgument_Texture2D(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "texSpecular") == LUA_TUSERDATA, index, "Expected Material");
+ result.texSpecular = LuaGetArgument_Texture2D(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "colDiffuse") == LUA_TTABLE, index, "Expected Material");
+ result.colDiffuse = LuaGetArgument_Color(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "colAmbient") == LUA_TTABLE, index, "Expected Material");
+ result.colAmbient = LuaGetArgument_Color(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "colSpecular") == LUA_TTABLE, index, "Expected Material");
+ result.colSpecular = LuaGetArgument_Color(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "glossiness") == LUA_TNUMBER, index, "Expected Material");
+ result.glossiness = LuaGetArgument_float(L, -1);
+ lua_pop(L, 8);
+ return result;
+}
+
+static Model LuaGetArgument_Model(lua_State* L, int index)
+{
+ Model result;
+ index = lua_absindex(L, index); // Makes sure we use absolute indices because we push multiple values
+ luaL_argcheck(L, lua_getfield(L, index, "mesh") == LUA_TUSERDATA, index, "Expected Model");
+ result.mesh = LuaGetArgument_Mesh(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "transform") == LUA_TTABLE, index, "Expected Model");
+ result.transform = LuaGetArgument_Matrix(L, -1);
+ luaL_argcheck(L, lua_getfield(L, index, "material") == LUA_TTABLE, index, "Expected Model");
+ result.material = LuaGetArgument_Material(L, -1);
+ lua_pop(L, 3);
+ return result;
+}
+
+//----------------------------------------------------------------------------------
+// LuaPush functions
+//----------------------------------------------------------------------------------
+static void LuaPush_Color(lua_State* L, Color color)
+{
+ lua_createtable(L, 0, 4);
+ lua_pushinteger(L, color.r);
+ lua_setfield(L, -2, "r");
+ lua_pushinteger(L, color.g);
+ lua_setfield(L, -2, "g");
+ lua_pushinteger(L, color.b);
+ lua_setfield(L, -2, "b");
+ lua_pushinteger(L, color.a);
+ lua_setfield(L, -2, "a");
+}
+
+static void LuaPush_Vector2(lua_State* L, Vector2 vec)
+{
+ lua_createtable(L, 0, 2);
+ lua_pushnumber(L, vec.x);
+ lua_setfield(L, -2, "x");
+ lua_pushnumber(L, vec.y);
+ lua_setfield(L, -2, "y");
+}
+
+static void LuaPush_Vector3(lua_State* L, Vector3 vec)
+{
+ lua_createtable(L, 0, 3);
+ lua_pushnumber(L, vec.x);
+ lua_setfield(L, -2, "x");
+ lua_pushnumber(L, vec.y);
+ lua_setfield(L, -2, "y");
+ lua_pushnumber(L, vec.z);
+ lua_setfield(L, -2, "z");
+}
+
+static void LuaPush_Quaternion(lua_State* L, Quaternion vec)
+{
+ lua_createtable(L, 0, 4);
+ lua_pushnumber(L, vec.x);
+ lua_setfield(L, -2, "x");
+ lua_pushnumber(L, vec.y);
+ lua_setfield(L, -2, "y");
+ lua_pushnumber(L, vec.z);
+ lua_setfield(L, -2, "z");
+ lua_pushnumber(L, vec.w);
+ lua_setfield(L, -2, "w");
+}
+
+static void LuaPush_Matrix(lua_State* L, Matrix *matrix)
+{
+ int i;
+ lua_createtable(L, 16, 0);
+ float* num = (&matrix->m0);
+ for (i = 0; i < 16; i++)
+ {
+ lua_pushnumber(L, num[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+}
+
+static void LuaPush_Rectangle(lua_State* L, Rectangle rect)
+{
+ lua_createtable(L, 0, 4);
+ lua_pushinteger(L, rect.x);
+ lua_setfield(L, -2, "x");
+ lua_pushinteger(L, rect.y);
+ lua_setfield(L, -2, "y");
+ lua_pushinteger(L, rect.width);
+ lua_setfield(L, -2, "width");
+ lua_pushinteger(L, rect.height);
+ lua_setfield(L, -2, "height");
+}
+
+static void LuaPush_Ray(lua_State* L, Ray ray)
+{
+ lua_createtable(L, 0, 2);
+ LuaPush_Vector3(L, ray.position);
+ lua_setfield(L, -2, "position");
+ LuaPush_Vector3(L, ray.direction);
+ lua_setfield(L, -2, "direction");
+}
+
+static void LuaPush_BoundingBox(lua_State* L, BoundingBox bb)
+{
+ lua_createtable(L, 0, 2);
+ LuaPush_Vector3(L, bb.min);
+ lua_setfield(L, -2, "min");
+ LuaPush_Vector3(L, bb.max);
+ lua_setfield(L, -2, "max");
+}
+
+static void LuaPush_Camera(lua_State* L, Camera cam)
+{
+ lua_createtable(L, 0, 4);
+ LuaPush_Vector3(L, cam.position);
+ lua_setfield(L, -2, "position");
+ LuaPush_Vector3(L, cam.target);
+ lua_setfield(L, -2, "target");
+ LuaPush_Vector3(L, cam.up);
+ lua_setfield(L, -2, "up");
+ lua_pushnumber(L, cam.fovy);
+ lua_setfield(L, -2, "fovy");
+}
+
+static void LuaPush_Camera2D(lua_State* L, Camera2D cam)
+{
+ lua_createtable(L, 0, 4);
+ LuaPush_Vector2(L, cam.offset);
+ lua_setfield(L, -2, "offset");
+ LuaPush_Vector2(L, cam.target);
+ lua_setfield(L, -2, "target");
+ lua_pushnumber(L, cam.rotation);
+ lua_setfield(L, -2, "rotation");
+ lua_pushnumber(L, cam.zoom);
+ lua_setfield(L, -2, "zoom");
+}
+
+static void LuaPush_Material(lua_State* L, Material mat)
+{
+ lua_createtable(L, 0, 8);
+ LuaPush_Shader(L, mat.shader);
+ lua_setfield(L, -2, "shader");
+ LuaPush_Texture2D(L, mat.texDiffuse);
+ lua_setfield(L, -2, "texDiffuse");
+ LuaPush_Texture2D(L, mat.texNormal);
+ lua_setfield(L, -2, "texNormal");
+ LuaPush_Texture2D(L, mat.texSpecular);
+ lua_setfield(L, -2, "texSpecular");
+ LuaPush_Color(L, mat.colDiffuse);
+ lua_setfield(L, -2, "colDiffuse");
+ LuaPush_Color(L, mat.colAmbient);
+ lua_setfield(L, -2, "colAmbient");
+ LuaPush_Color(L, mat.colSpecular);
+ lua_setfield(L, -2, "colSpecular");
+ lua_pushnumber(L, mat.glossiness);
+ lua_setfield(L, -2, "glossiness");
+}
+
+static void LuaPush_Model(lua_State* L, Model mdl)
+{
+ lua_createtable(L, 0, 4);
+ LuaPush_Mesh(L, mdl.mesh);
+ lua_setfield(L, -2, "mesh");
+ LuaPush_Matrix(L, &mdl.transform);
+ lua_setfield(L, -2, "transform");
+ LuaPush_Material(L, mdl.material);
+ lua_setfield(L, -2, "material");
+}
+
+//----------------------------------------------------------------------------------
+// raylib Lua Structure constructors
+//----------------------------------------------------------------------------------
+static int lua_Color(lua_State* L)
+{
+ LuaPush_Color(L, (Color) { (unsigned char)luaL_checkinteger(L, 1), (unsigned char)luaL_checkinteger(L, 2), (unsigned char)luaL_checkinteger(L, 3), (unsigned char)luaL_checkinteger(L, 4) });
+ return 1;
+}
+
+static int lua_Vector2(lua_State* L)
+{
+ LuaPush_Vector2(L, (Vector2) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2) });
+ return 1;
+}
+
+static int lua_Vector3(lua_State* L)
+{
+ LuaPush_Vector3(L, (Vector3) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3) });
+ return 1;
+}
+
+static int lua_Quaternion(lua_State* L)
+{
+ LuaPush_Quaternion(L, (Quaternion) { (float)luaL_checknumber(L, 1), (float)luaL_checknumber(L, 2), (float)luaL_checknumber(L, 3), (float)luaL_checknumber(L, 4) });
+ return 1;
+}
+
+static int lua_Rectangle(lua_State* L)
+{
+ LuaPush_Rectangle(L, (Rectangle) { (int)luaL_checkinteger(L, 1), (int)luaL_checkinteger(L, 2), (int)luaL_checkinteger(L, 3), (int)luaL_checkinteger(L, 4) });
+ return 1;
+}
+
+static int lua_Ray(lua_State* L)
+{
+ Vector2 pos = LuaGetArgument_Vector2(L, 1);
+ Vector2 dir = LuaGetArgument_Vector2(L, 2);
+ LuaPush_Ray(L, (Ray) { { pos.x, pos.y }, { dir.x, dir.y } });
+ return 1;
+}
+
+static int lua_BoundingBox(lua_State* L)
+{
+ Vector3 min = LuaGetArgument_Vector3(L, 1);
+ Vector3 max = LuaGetArgument_Vector3(L, 2);
+ LuaPush_BoundingBox(L, (BoundingBox) { { min.x, min.y, min.z }, { max.x, max.y, max.z } });
+ return 1;
+}
+
+static int lua_Camera(lua_State* L)
+{
+ Vector3 pos = LuaGetArgument_Vector3(L, 1);
+ Vector3 tar = LuaGetArgument_Vector3(L, 2);
+ Vector3 up = LuaGetArgument_Vector3(L, 3);
+ float fovy = LuaGetArgument_float(L, 4);
+ LuaPush_Camera(L, (Camera) { { pos.x, pos.y, pos.z }, { tar.x, tar.y, tar.z }, { up.x, up.y, up.z }, fovy });
+ return 1;
+}
+
+static int lua_Camera2D(lua_State* L)
+{
+ Vector2 off = LuaGetArgument_Vector2(L, 1);
+ Vector2 tar = LuaGetArgument_Vector2(L, 2);
+ float rot = LuaGetArgument_float(L, 3);
+ float zoom = LuaGetArgument_float(L, 4);
+ LuaPush_Camera2D(L, (Camera2D) { { off.x, off.y }, { tar.x, tar.y }, rot, zoom });
+ return 1;
+}
+
+/*************************************************************************************
+* raylib Lua Functions Bindings
+**************************************************************************************/
+
+//------------------------------------------------------------------------------------
+// raylib [core] module functions - Window and Graphics Device
+//------------------------------------------------------------------------------------
+int lua_InitWindow(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ const char * arg3 = LuaGetArgument_string(L, 3);
+ InitWindow(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_CloseWindow(lua_State* L)
+{
+ CloseWindow();
+ return 0;
+}
+
+int lua_WindowShouldClose(lua_State* L)
+{
+ bool result = WindowShouldClose();
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsWindowMinimized(lua_State* L)
+{
+ bool result = IsWindowMinimized();
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_ToggleFullscreen(lua_State* L)
+{
+ ToggleFullscreen();
+ return 0;
+}
+
+int lua_GetScreenWidth(lua_State* L)
+{
+ int result = GetScreenWidth();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetScreenHeight(lua_State* L)
+{
+ int result = GetScreenHeight();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_ShowCursor(lua_State* L)
+{
+ ShowCursor();
+ return 0;
+}
+
+int lua_HideCursor(lua_State* L)
+{
+ HideCursor();
+ return 0;
+}
+
+int lua_IsCursorHidden(lua_State* L)
+{
+ bool result = IsCursorHidden();
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_EnableCursor(lua_State* L)
+{
+ EnableCursor();
+ return 0;
+}
+
+int lua_DisableCursor(lua_State* L)
+{
+ DisableCursor();
+ return 0;
+}
+
+int lua_ClearBackground(lua_State* L)
+{
+ Color arg1 = LuaGetArgument_Color(L, 1);
+ ClearBackground(arg1);
+ return 0;
+}
+
+int lua_BeginDrawing(lua_State* L)
+{
+ BeginDrawing();
+ return 0;
+}
+
+int lua_EndDrawing(lua_State* L)
+{
+ EndDrawing();
+ return 0;
+}
+
+int lua_Begin2dMode(lua_State* L)
+{
+ Camera2D arg1 = LuaGetArgument_Camera2D(L, 1);
+ Begin2dMode(arg1);
+ return 0;
+}
+
+int lua_End2dMode(lua_State* L)
+{
+ End2dMode();
+ return 0;
+}
+
+int lua_Begin3dMode(lua_State* L)
+{
+ Camera arg1 = LuaGetArgument_Camera(L, 1);
+ Begin3dMode(arg1);
+ return 0;
+}
+
+int lua_End3dMode(lua_State* L)
+{
+ End3dMode();
+ return 0;
+}
+
+int lua_BeginTextureMode(lua_State* L)
+{
+ RenderTexture2D arg1 = LuaGetArgument_RenderTexture2D(L, 1);
+ BeginTextureMode(arg1);
+ return 0;
+}
+
+int lua_EndTextureMode(lua_State* L)
+{
+ EndTextureMode();
+ return 0;
+}
+
+int lua_GetMouseRay(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Camera arg2 = LuaGetArgument_Camera(L, 2);
+ Ray result = GetMouseRay(arg1, arg2);
+ LuaPush_Ray(L, result);
+ return 1;
+}
+
+int lua_GetWorldToScreen(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Camera arg2 = LuaGetArgument_Camera(L, 2);
+ Vector2 result = GetWorldToScreen(arg1, arg2);
+ LuaPush_Vector2(L, result);
+ return 1;
+}
+
+int lua_GetCameraMatrix(lua_State* L)
+{
+ Camera arg1 = LuaGetArgument_Camera(L, 1);
+ Matrix result = GetCameraMatrix(arg1);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+#if defined(PLATFORM_WEB)
+
+static int LuaDrawLoopFunc;
+
+static void LuaDrawLoop()
+{
+ lua_rawgeti(L, LUA_REGISTRYINDEX, LuaDrawLoopFunc);
+ lua_call(L, 0, 0);
+}
+
+int lua_SetDrawingLoop(lua_State* L)
+{
+ luaL_argcheck(L, lua_isfunction(L, 1), 1, "Loop function expected");
+ lua_pushvalue(L, 1);
+ LuaDrawLoopFunc = luaL_ref(L, LUA_REGISTRYINDEX);
+ SetDrawingLoop(&LuaDrawLoop);
+ return 0;
+}
+
+#else
+
+int lua_SetTargetFPS(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ SetTargetFPS(arg1);
+ return 0;
+}
+#endif
+
+int lua_GetFPS(lua_State* L)
+{
+ float result = GetFPS();
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_GetFrameTime(lua_State* L)
+{
+ float result = GetFrameTime();
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_GetColor(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ Color result = GetColor(arg1);
+ LuaPush_Color(L, result);
+ return 1;
+}
+
+int lua_GetHexValue(lua_State* L)
+{
+ Color arg1 = LuaGetArgument_Color(L, 1);
+ int result = GetHexValue(arg1);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_ColorToFloat(lua_State* L)
+{
+ Color arg1 = LuaGetArgument_Color(L, 1);
+ float * result = ColorToFloat(arg1);
+ lua_createtable(L, 4, 0);
+ for (int i = 0; i < 4; i++)
+ {
+ lua_pushnumber(L, result[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ free(result);
+ return 1;
+}
+
+int lua_VectorToFloat(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float * result = VectorToFloat(arg1);
+ lua_createtable(L, 3, 0);
+ for (int i = 0; i < 3; i++)
+ {
+ lua_pushnumber(L, result[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ free(result);
+ return 1;
+}
+
+int lua_MatrixToFloat(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ float * result = MatrixToFloat(arg1);
+ lua_createtable(L, 16, 0);
+ for (int i = 0; i < 16; i++)
+ {
+ lua_pushnumber(L, result[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ free(result);
+ return 1;
+}
+
+int lua_GetRandomValue(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int result = GetRandomValue(arg1, arg2);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_Fade(lua_State* L)
+{
+ Color arg1 = LuaGetArgument_Color(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Color result = Fade(arg1, arg2);
+ LuaPush_Color(L, result);
+ return 1;
+}
+
+int lua_SetConfigFlags(lua_State* L)
+{
+ char arg1 = LuaGetArgument_char(L, 1);
+ SetConfigFlags(arg1);
+ return 0;
+}
+
+int lua_ShowLogo(lua_State* L)
+{
+ ShowLogo();
+ return 0;
+}
+
+int lua_IsFileDropped(lua_State* L)
+{
+ bool result = IsFileDropped();
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_GetDroppedFiles(lua_State* L)
+{
+ int count = 0;
+ char ** result = GetDroppedFiles(&count);
+ lua_createtable(L, count, 0);
+ for (int i = 0; i < count; i++)
+ {
+ lua_pushstring(L, result[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ return 1;
+}
+
+int lua_ClearDroppedFiles(lua_State* L)
+{
+ ClearDroppedFiles();
+ return 0;
+}
+
+int lua_StorageSaveValue(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ StorageSaveValue(arg1, arg2);
+ return 0;
+}
+
+int lua_StorageLoadValue(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int result = StorageLoadValue(arg1);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [core] module functions - Input Handling
+//------------------------------------------------------------------------------------
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+int lua_IsKeyPressed(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsKeyPressed(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsKeyDown(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsKeyDown(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsKeyReleased(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsKeyReleased(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsKeyUp(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsKeyUp(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_GetKeyPressed(lua_State* L)
+{
+ int result = GetKeyPressed();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_SetExitKey(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ SetExitKey(arg1);
+ return 0;
+}
+
+int lua_IsGamepadAvailable(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsGamepadAvailable(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_GetGamepadAxisMovement(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ float result = GetGamepadAxisMovement(arg1, arg2);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_IsGamepadButtonPressed(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ bool result = IsGamepadButtonPressed(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsGamepadButtonDown(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ bool result = IsGamepadButtonDown(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsGamepadButtonReleased(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ bool result = IsGamepadButtonReleased(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsGamepadButtonUp(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ bool result = IsGamepadButtonUp(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+#endif
+
+int lua_IsMouseButtonPressed(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsMouseButtonPressed(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsMouseButtonDown(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsMouseButtonDown(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsMouseButtonReleased(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsMouseButtonReleased(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsMouseButtonUp(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsMouseButtonUp(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_GetMouseX(lua_State* L)
+{
+ int result = GetMouseX();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetMouseY(lua_State* L)
+{
+ int result = GetMouseY();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetMousePosition(lua_State* L)
+{
+ Vector2 result = GetMousePosition();
+ LuaPush_Vector2(L, result);
+ return 1;
+}
+
+int lua_SetMousePosition(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ SetMousePosition(arg1);
+ return 0;
+}
+
+int lua_GetMouseWheelMove(lua_State* L)
+{
+ int result = GetMouseWheelMove();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetTouchX(lua_State* L)
+{
+ int result = GetTouchX();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetTouchY(lua_State* L)
+{
+ int result = GetTouchY();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetTouchPosition(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ Vector2 result = GetTouchPosition(arg1);
+ LuaPush_Vector2(L, result);
+ return 1;
+}
+
+
+#if defined(PLATFORM_ANDROID)
+int lua_IsButtonPressed(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsButtonPressed(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsButtonDown(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsButtonDown(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_IsButtonReleased(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsButtonReleased(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+#endif
+
+//------------------------------------------------------------------------------------
+// raylib [gestures] module functions - Gestures and Touch Handling
+//------------------------------------------------------------------------------------
+int lua_SetGesturesEnabled(lua_State* L)
+{
+ unsigned arg1 = LuaGetArgument_unsigned(L, 1);
+ SetGesturesEnabled(arg1);
+ return 0;
+}
+
+int lua_IsGestureDetected(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ bool result = IsGestureDetected(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_GetTouchPointsCount(lua_State* L)
+{
+ int result = GetTouchPointsCount();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetGestureDetected(lua_State* L)
+{
+ int result = GetGestureDetected();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetGestureHoldDuration(lua_State* L)
+{
+ int result = GetGestureHoldDuration();
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_GetGestureDragVector(lua_State* L)
+{
+ Vector2 result = GetGestureDragVector();
+ LuaPush_Vector2(L, result);
+ return 1;
+}
+
+int lua_GetGestureDragAngle(lua_State* L)
+{
+ float result = GetGestureDragAngle();
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_GetGesturePinchVector(lua_State* L)
+{
+ Vector2 result = GetGesturePinchVector();
+ LuaPush_Vector2(L, result);
+ return 1;
+}
+
+int lua_GetGesturePinchAngle(lua_State* L)
+{
+ float result = GetGesturePinchAngle();
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [camera] module functions - Camera System
+//------------------------------------------------------------------------------------
+int lua_SetCameraMode(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ SetCameraMode(arg1);
+ return 0;
+}
+
+int lua_UpdateCamera(lua_State* L)
+{
+ Camera arg1 = LuaGetArgument_Camera(L, 1);
+ UpdateCamera(&arg1);
+ LuaPush_Camera(L, arg1);
+ return 1;
+}
+
+int lua_UpdateCameraPlayer(lua_State* L)
+{
+ Camera arg1 = LuaGetArgument_Camera(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ UpdateCameraPlayer(&arg1, &arg2);
+ LuaPush_Camera(L, arg1);
+ LuaPush_Vector3(L, arg2);
+ return 2;
+}
+
+int lua_SetCameraPosition(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ SetCameraPosition(arg1);
+ return 0;
+}
+
+int lua_SetCameraTarget(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ SetCameraTarget(arg1);
+ return 0;
+}
+
+int lua_SetCameraFovy(lua_State* L)
+{
+ float arg1 = LuaGetArgument_float(L, 1);
+ SetCameraFovy(arg1);
+ return 0;
+}
+
+int lua_SetCameraPanControl(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ SetCameraPanControl(arg1);
+ return 0;
+}
+
+int lua_SetCameraAltControl(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ SetCameraAltControl(arg1);
+ return 0;
+}
+
+int lua_SetCameraSmoothZoomControl(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ SetCameraSmoothZoomControl(arg1);
+ return 0;
+}
+
+int lua_SetCameraMoveControls(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ int arg5 = LuaGetArgument_int(L, 5);
+ int arg6 = LuaGetArgument_int(L, 6);
+ SetCameraMoveControls(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_SetCameraMouseSensitivity(lua_State* L)
+{
+ float arg1 = LuaGetArgument_float(L, 1);
+ SetCameraMouseSensitivity(arg1);
+ return 0;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [shapes] module functions - Basic Shapes Drawing
+//------------------------------------------------------------------------------------
+int lua_DrawPixel(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawPixel(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawPixelV(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Color arg2 = LuaGetArgument_Color(L, 2);
+ DrawPixelV(arg1, arg2);
+ return 0;
+}
+
+int lua_DrawLine(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawLine(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawLineV(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawLineV(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawCircle(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawCircle(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawCircleGradient(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawCircleGradient(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawCircleV(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawCircleV(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawCircleLines(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawCircleLines(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawRectangle(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawRectangle(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawRectangleRec(lua_State* L)
+{
+ Rectangle arg1 = LuaGetArgument_Rectangle(L, 1);
+ Color arg2 = LuaGetArgument_Color(L, 2);
+ DrawRectangleRec(arg1, arg2);
+ return 0;
+}
+
+int lua_DrawRectangleGradient(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawRectangleGradient(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_DrawRectangleV(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawRectangleV(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawRectangleLines(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawRectangleLines(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawTriangle(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawTriangle(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawTriangleLines(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawTriangleLines(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawPoly(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawPoly(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+#define GET_TABLE(type, name, index) \
+ type* name = 0; \
+ size_t name##_size = 0; \
+ { \
+ size_t sz = 0; \
+ luaL_checktype(L, index, LUA_TTABLE); \
+ lua_pushnil(L); \
+ while (lua_next(L, index)) { \
+ LuaGetArgument_##type(L, -1); \
+ sz++; \
+ lua_pop(L, 1); \
+ } \
+ name = calloc(sz, sizeof(type)); \
+ sz = 0; \
+ lua_pushnil(L); \
+ while (lua_next(L, index)) { \
+ name[sz] = LuaGetArgument_##type(L, -1); \
+ sz++; \
+ lua_pop(L, 1); \
+ } \
+ lua_pop(L, 1); \
+ name##_size = sz; \
+ }
+
+
+int lua_DrawPolyEx(lua_State* L)
+{
+ GET_TABLE(Vector2, arg1, 1);
+ Color arg2 = LuaGetArgument_Color(L, 2);
+ DrawPolyEx(arg1, arg1_size, arg2);
+ free(arg1);
+ return 0;
+}
+
+int lua_DrawPolyExLines(lua_State* L)
+{
+ GET_TABLE(Vector2, arg1, 1);
+ Color arg2 = LuaGetArgument_Color(L, 2);
+ DrawPolyExLines(arg1, arg1_size, arg2);
+ free(arg1);
+ return 0;
+}
+
+int lua_CheckCollisionRecs(lua_State* L)
+{
+ Rectangle arg1 = LuaGetArgument_Rectangle(L, 1);
+ Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+ bool result = CheckCollisionRecs(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionCircles(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ bool result = CheckCollisionCircles(arg1, arg2, arg3, arg4);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionCircleRec(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Rectangle arg3 = LuaGetArgument_Rectangle(L, 3);
+ bool result = CheckCollisionCircleRec(arg1, arg2, arg3);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_GetCollisionRec(lua_State* L)
+{
+ Rectangle arg1 = LuaGetArgument_Rectangle(L, 1);
+ Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+ Rectangle result = GetCollisionRec(arg1, arg2);
+ LuaPush_Rectangle(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionPointRec(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+ bool result = CheckCollisionPointRec(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionPointCircle(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ bool result = CheckCollisionPointCircle(arg1, arg2, arg3);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionPointTriangle(lua_State* L)
+{
+ Vector2 arg1 = LuaGetArgument_Vector2(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+ Vector2 arg4 = LuaGetArgument_Vector2(L, 4);
+ bool result = CheckCollisionPointTriangle(arg1, arg2, arg3, arg4);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [textures] module functions - Texture Loading and Drawing
+//------------------------------------------------------------------------------------
+int lua_LoadImage(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ Image result = LoadImage(arg1);
+ LuaPush_Image(L, result);
+ return 1;
+}
+
+int lua_LoadImageEx(lua_State* L)
+{
+ GET_TABLE(Color, arg1, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ Image result = LoadImageEx(arg1, arg2, arg3); // ISSUE: #3 number expected, got no value
+ LuaPush_Image(L, result);
+ free(arg1);
+ return 1;
+}
+
+int lua_LoadImageRaw(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ int arg5 = LuaGetArgument_int(L, 5);
+ Image result = LoadImageRaw(arg1, arg2, arg3, arg4, arg5);
+ LuaPush_Image(L, result);
+ return 1;
+}
+
+int lua_LoadImageFromRES(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ Image result = LoadImageFromRES(arg1, arg2);
+ LuaPush_Image(L, result);
+ return 1;
+}
+
+int lua_LoadTexture(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ Texture2D result = LoadTexture(arg1);
+ LuaPush_Texture2D(L, result);
+ return 1;
+}
+
+int lua_LoadTextureEx(lua_State* L)
+{
+ void * arg1 = (char *)LuaGetArgument_string(L, 1); // NOTE: getting argument as string?
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Texture2D result = LoadTextureEx(arg1, arg2, arg3, arg4);
+ LuaPush_Texture2D(L, result);
+ return 1;
+}
+
+int lua_LoadTextureFromRES(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ Texture2D result = LoadTextureFromRES(arg1, arg2);
+ LuaPush_Texture2D(L, result);
+ return 1;
+}
+
+int lua_LoadTextureFromImage(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Texture2D result = LoadTextureFromImage(arg1);
+ LuaPush_Texture2D(L, result);
+ return 1;
+}
+
+int lua_LoadRenderTexture(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ RenderTexture2D result = LoadRenderTexture(arg1, arg2);
+ LuaPush_RenderTexture2D(L, result);
+ return 1;
+}
+
+int lua_UnloadImage(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ UnloadImage(arg1);
+ return 0;
+}
+
+int lua_UnloadTexture(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ UnloadTexture(arg1);
+ return 0;
+}
+
+int lua_UnloadRenderTexture(lua_State* L)
+{
+ RenderTexture2D arg1 = LuaGetArgument_RenderTexture2D(L, 1);
+ UnloadRenderTexture(arg1);
+ return 0;
+}
+
+int lua_GetImageData(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Color * result = GetImageData(arg1);
+ lua_createtable(L, arg1.width*arg1.height, 0);
+ for (int i = 0; i < arg1.width*arg1.height; i++)
+ {
+ LuaPush_Color(L, result[i]);
+ lua_rawseti(L, -2, i + 1);
+ }
+ free(result);
+ return 1;
+}
+
+int lua_GetTextureData(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ Image result = GetTextureData(arg1);
+ LuaPush_Image(L, result);
+ return 1;
+}
+
+int lua_ImageToPOT(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Color arg2 = LuaGetArgument_Color(L, 2);
+ ImageToPOT(&arg1, arg2);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageFormat(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ ImageFormat(&arg1, arg2);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageDither(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ int arg5 = LuaGetArgument_int(L, 5);
+ ImageDither(&arg1, arg2, arg3, arg4, arg5);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageCopy(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Image result = ImageCopy(arg1);
+ LuaPush_Image(L, result);
+ return 1;
+}
+
+int lua_ImageCrop(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+ ImageCrop(&arg1, arg2);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageResize(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ ImageResize(&arg1, arg2, arg3);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageResizeNN(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ ImageResizeNN(&arg1, arg2, arg3);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageText(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ Image result = ImageText(arg1, arg2, arg3);
+ LuaPush_Image(L, result);
+ return 1;
+}
+
+int lua_ImageTextEx(lua_State* L)
+{
+ SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1);
+ const char * arg2 = LuaGetArgument_string(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ Image result = ImageTextEx(arg1, arg2, arg3, arg4, arg5);
+ LuaPush_Image(L, result);
+ return 1;
+}
+
+int lua_ImageDraw(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Image arg2 = LuaGetArgument_Image(L, 2);
+ Rectangle arg3 = LuaGetArgument_Rectangle(L, 3);
+ Rectangle arg4 = LuaGetArgument_Rectangle(L, 4);
+ ImageDraw(&arg1, arg2, arg3, arg4);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageDrawText(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ const char * arg3 = LuaGetArgument_string(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ ImageDrawText(&arg1, arg2, arg3, arg4, arg5);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageDrawTextEx(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ SpriteFont arg3 = LuaGetArgument_SpriteFont(L, 3);
+ const char * arg4 = LuaGetArgument_string(L, 4);
+ float arg5 = LuaGetArgument_float(L, 5);
+ int arg6 = LuaGetArgument_int(L, 6);
+ Color arg7 = LuaGetArgument_Color(L, 7);
+ ImageDrawTextEx(&arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageFlipVertical(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ ImageFlipVertical(&arg1);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageFlipHorizontal(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ ImageFlipHorizontal(&arg1);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageColorTint(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Color arg2 = LuaGetArgument_Color(L, 2);
+ ImageColorTint(&arg1, arg2);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageColorInvert(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ ImageColorInvert(&arg1);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageColorGrayscale(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ ImageColorGrayscale(&arg1);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageColorContrast(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ ImageColorContrast(&arg1, arg2);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_ImageColorBrightness(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ ImageColorBrightness(&arg1, arg2);
+ LuaPush_Image(L, arg1);
+ return 1;
+}
+
+int lua_GenTextureMipmaps(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ GenTextureMipmaps(arg1);
+ return 0;
+}
+
+int lua_UpdateTexture(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ void * arg2 = (char *)LuaGetArgument_string(L, 2); // NOTE: Getting (void *) as string?
+ UpdateTexture(arg1, arg2); // ISSUE: #2 string expected, got table -> GetImageData() returns a table!
+ return 0;
+}
+
+int lua_DrawTexture(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawTexture(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawTextureV(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawTextureV(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawTextureEx(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawTextureEx(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawTextureRec(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+ Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawTextureRec(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawTexturePro(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ Rectangle arg2 = LuaGetArgument_Rectangle(L, 2);
+ Rectangle arg3 = LuaGetArgument_Rectangle(L, 3);
+ Vector2 arg4 = LuaGetArgument_Vector2(L, 4);
+ float arg5 = LuaGetArgument_float(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawTexturePro(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [text] module functions - Font Loading and Text Drawing
+//------------------------------------------------------------------------------------
+int lua_GetDefaultFont(lua_State* L)
+{
+ SpriteFont result = GetDefaultFont();
+ LuaPush_SpriteFont(L, result);
+ return 1;
+}
+
+int lua_LoadSpriteFont(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ SpriteFont result = LoadSpriteFont(arg1);
+ LuaPush_SpriteFont(L, result);
+ return 1;
+}
+
+int lua_UnloadSpriteFont(lua_State* L)
+{
+ SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1);
+ UnloadSpriteFont(arg1);
+ return 0;
+}
+
+int lua_DrawText(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawText(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawTextEx(lua_State* L)
+{
+ SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1);
+ const char * arg2 = LuaGetArgument_string(L, 2);
+ Vector2 arg3 = LuaGetArgument_Vector2(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ int arg5 = LuaGetArgument_int(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawTextEx(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_MeasureText(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int result = MeasureText(arg1, arg2);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_MeasureTextEx(lua_State* L)
+{
+ SpriteFont arg1 = LuaGetArgument_SpriteFont(L, 1);
+ const char * arg2 = LuaGetArgument_string(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Vector2 result = MeasureTextEx(arg1, arg2, arg3, arg4);
+ LuaPush_Vector2(L, result);
+ return 1;
+}
+
+int lua_DrawFPS(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ DrawFPS(arg1, arg2);
+ return 0;
+}
+
+// NOTE: FormatText() can be replaced by Lua function: string.format()
+// NOTE: SubText() can be replaced by Lua function: string.sub()
+
+//------------------------------------------------------------------------------------
+// raylib [models] module functions - Basic 3d Shapes Drawing Functions
+//------------------------------------------------------------------------------------
+int lua_DrawLine3D(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawLine3D(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawCircle3D(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Vector3 arg4 = LuaGetArgument_Vector3(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawCircle3D(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawCube(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawCube(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawCubeV(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawCubeV(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawCubeWires(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawCubeWires(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawCubeTexture(lua_State* L)
+{
+ Texture2D arg1 = LuaGetArgument_Texture2D(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ float arg5 = LuaGetArgument_float(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawCubeTexture(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_DrawSphere(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawSphere(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawSphereEx(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawSphereEx(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawSphereWires(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawSphereWires(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawCylinder(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ int arg5 = LuaGetArgument_int(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawCylinder(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_DrawCylinderWires(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ int arg5 = LuaGetArgument_int(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawCylinderWires(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_DrawPlane(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector2 arg2 = LuaGetArgument_Vector2(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ DrawPlane(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_DrawRay(lua_State* L)
+{
+ Ray arg1 = LuaGetArgument_Ray(L, 1);
+ Color arg2 = LuaGetArgument_Color(L, 2);
+ DrawRay(arg1, arg2);
+ return 0;
+}
+
+int lua_DrawGrid(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ DrawGrid(arg1, arg2);
+ return 0;
+}
+
+int lua_DrawGizmo(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ DrawGizmo(arg1);
+ return 0;
+}
+
+int lua_DrawLight(lua_State* L)
+{
+ Light arg1 = LuaGetArgument_Light(L, 1);
+ DrawLight(arg1);
+ return 0;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [models] module functions
+//------------------------------------------------------------------------------------
+int lua_LoadModel(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ Model result = LoadModel(arg1);
+ LuaPush_Model(L, result);
+ return 1;
+}
+
+int lua_LoadModelEx(lua_State* L)
+{
+ Mesh arg1 = LuaGetArgument_Mesh(L, 1);
+ bool arg2 = LuaGetArgument_int(L, 2);
+ Model result = LoadModelEx(arg1, arg2);
+ LuaPush_Model(L, result);
+ return 1;
+}
+
+int lua_LoadModelFromRES(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ Model result = LoadModelFromRES(arg1, arg2);
+ LuaPush_Model(L, result);
+ return 1;
+}
+
+int lua_LoadHeightmap(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Model result = LoadHeightmap(arg1, arg2);
+ LuaPush_Model(L, result);
+ return 1;
+}
+
+int lua_LoadCubicmap(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Model result = LoadCubicmap(arg1);
+ LuaPush_Model(L, result);
+ return 1;
+}
+
+int lua_UnloadModel(lua_State* L)
+{
+ Model arg1 = LuaGetArgument_Model(L, 1);
+ UnloadModel(arg1);
+ return 0;
+}
+
+// TODO: GenMesh*() functionality (not ready yet on raylib 1.6)
+
+int lua_LoadMaterial(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ Material result = LoadMaterial(arg1);
+ LuaPush_Material(L, result);
+ return 1;
+}
+
+int lua_LoadDefaultMaterial(lua_State* L)
+{
+ Material result = LoadDefaultMaterial();
+ LuaPush_Material(L, result);
+ return 1;
+}
+
+int lua_LoadStandardMaterial(lua_State* L)
+{
+ Material result = LoadStandardMaterial();
+ LuaPush_Material(L, result);
+ return 1;
+}
+
+int lua_UnloadMaterial(lua_State* L)
+{
+ Material arg1 = LuaGetArgument_Material(L, 1);
+ UnloadMaterial(arg1);
+ return 0;
+}
+
+int lua_DrawModel(lua_State* L)
+{
+ Model arg1 = LuaGetArgument_Model(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawModel(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawModelEx(lua_State* L)
+{
+ Model arg1 = LuaGetArgument_Model(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Vector3 arg5 = LuaGetArgument_Vector3(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawModelEx(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_DrawModelWires(lua_State* L)
+{
+ Model arg1 = LuaGetArgument_Model(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Color arg4 = LuaGetArgument_Color(L, 4);
+ DrawModelWires(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_DrawModelWiresEx(lua_State* L)
+{
+ Model arg1 = LuaGetArgument_Model(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Vector3 arg5 = LuaGetArgument_Vector3(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawModelWiresEx(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_DrawBillboard(lua_State* L)
+{
+ Camera arg1 = LuaGetArgument_Camera(L, 1);
+ Texture2D arg2 = LuaGetArgument_Texture2D(L, 2);
+ Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Color arg5 = LuaGetArgument_Color(L, 5);
+ DrawBillboard(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+
+int lua_DrawBillboardRec(lua_State* L)
+{
+ Camera arg1 = LuaGetArgument_Camera(L, 1);
+ Texture2D arg2 = LuaGetArgument_Texture2D(L, 2);
+ Rectangle arg3 = LuaGetArgument_Rectangle(L, 3);
+ Vector3 arg4 = LuaGetArgument_Vector3(L, 4);
+ float arg5 = LuaGetArgument_float(L, 5);
+ Color arg6 = LuaGetArgument_Color(L, 6);
+ DrawBillboardRec(arg1, arg2, arg3, arg4, arg5, arg6);
+ return 0;
+}
+
+int lua_CalculateBoundingBox(lua_State* L)
+{
+ Mesh arg1 = LuaGetArgument_Mesh(L, 1);
+ BoundingBox result = CalculateBoundingBox(arg1);
+ LuaPush_BoundingBox(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionSpheres(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ bool result = CheckCollisionSpheres(arg1, arg2, arg3, arg4);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionBoxes(lua_State* L)
+{
+ BoundingBox arg1 = LuaGetArgument_BoundingBox(L, 1);
+ BoundingBox arg2 = LuaGetArgument_BoundingBox(L, 2);
+ bool result = CheckCollisionBoxes(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionBoxSphere(lua_State* L)
+{
+ BoundingBox arg1 = LuaGetArgument_BoundingBox(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ bool result = CheckCollisionBoxSphere(arg1, arg2, arg3);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionRaySphere(lua_State* L)
+{
+ Ray arg1 = LuaGetArgument_Ray(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ bool result = CheckCollisionRaySphere(arg1, arg2, arg3);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_CheckCollisionRaySphereEx(lua_State* L)
+{
+ Ray arg1 = LuaGetArgument_Ray(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Vector3 arg4 = LuaGetArgument_Vector3(L, 4);
+ bool result = CheckCollisionRaySphereEx(arg1, arg2, arg3, &arg4);
+ lua_pushboolean(L, result);
+ LuaPush_Vector3(L, arg4);
+ return 2;
+}
+
+int lua_CheckCollisionRayBox(lua_State* L)
+{
+ Ray arg1 = LuaGetArgument_Ray(L, 1);
+ BoundingBox arg2 = LuaGetArgument_BoundingBox(L, 2);
+ bool result = CheckCollisionRayBox(arg1, arg2);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_ResolveCollisionCubicmap(lua_State* L)
+{
+ Image arg1 = LuaGetArgument_Image(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+ float arg4 = LuaGetArgument_float(L, 4);
+ Vector3 result = ResolveCollisionCubicmap(arg1, arg2, &arg3, arg4);
+ LuaPush_Vector3(L, result);
+ LuaPush_Vector3(L, arg3);
+ return 2;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [raymath] module functions - Shaders
+//------------------------------------------------------------------------------------
+int lua_LoadShader(lua_State* L)
+{
+ char * arg1 = (char *)LuaGetArgument_string(L, 1);
+ char * arg2 = (char *)LuaGetArgument_string(L, 2);
+ Shader result = LoadShader(arg1, arg2);
+ LuaPush_Shader(L, result);
+ return 1;
+}
+
+int lua_UnloadShader(lua_State* L)
+{
+ Shader arg1 = LuaGetArgument_Shader(L, 1);
+ UnloadShader(arg1);
+ return 0;
+}
+
+int lua_GetDefaultShader(lua_State* L)
+{
+ Shader result = GetDefaultShader();
+ LuaPush_Shader(L, result);
+ return 1;
+}
+
+int lua_GetStandardShader(lua_State* L)
+{
+ Shader result = GetStandardShader();
+ LuaPush_Shader(L, result);
+ return 1;
+}
+
+int lua_GetDefaultTexture(lua_State* L)
+{
+ Texture2D result = GetDefaultTexture();
+ LuaPush_Texture2D(L, result);
+ return 1;
+}
+
+int lua_GetShaderLocation(lua_State* L)
+{
+ Shader arg1 = LuaGetArgument_Shader(L, 1);
+ const char * arg2 = LuaGetArgument_string(L, 2);
+ int result = GetShaderLocation(arg1, arg2);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+int lua_SetShaderValue(lua_State* L)
+{
+ Shader arg1 = LuaGetArgument_Shader(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ GET_TABLE(float, arg3, 3);
+ SetShaderValue(arg1, arg2, arg3, arg3_size);
+ free(arg3);
+ return 0;
+}
+
+int lua_SetShaderValuei(lua_State* L)
+{
+ Shader arg1 = LuaGetArgument_Shader(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ GET_TABLE(int, arg3, 3);
+ SetShaderValuei(arg1, arg2, arg3, arg3_size);
+ free(arg3);
+ return 0;
+}
+
+int lua_SetShaderValueMatrix(lua_State* L)
+{
+ Shader arg1 = LuaGetArgument_Shader(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ Matrix arg3 = LuaGetArgument_Matrix(L, 3);
+ SetShaderValueMatrix(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_SetMatrixProjection(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ SetMatrixProjection(arg1);
+ return 0;
+}
+
+int lua_SetMatrixModelview(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ SetMatrixModelview(arg1);
+ return 0;
+}
+
+int lua_BeginShaderMode(lua_State* L)
+{
+ Shader arg1 = LuaGetArgument_Shader(L, 1);
+ BeginShaderMode(arg1);
+ return 0;
+}
+
+int lua_EndShaderMode(lua_State* L)
+{
+ EndShaderMode();
+ return 0;
+}
+
+int lua_BeginBlendMode(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ BeginBlendMode(arg1);
+ return 0;
+}
+
+int lua_EndBlendMode(lua_State* L)
+{
+ EndBlendMode();
+ return 0;
+}
+
+int lua_CreateLight(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Color arg3 = LuaGetArgument_Color(L, 3);
+ Light result = CreateLight(arg1, arg2, arg3);
+ LuaPush_Light(L, result);
+ return 1;
+}
+
+int lua_DestroyLight(lua_State* L)
+{
+ Light arg1 = LuaGetArgument_Light(L, 1);
+ DestroyLight(arg1);
+ return 0;
+}
+
+
+//------------------------------------------------------------------------------------
+// raylib [rlgl] module functions - VR experience
+//------------------------------------------------------------------------------------
+int lua_InitVrDevice(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ InitVrDevice(arg1);
+ return 0;
+}
+
+int lua_CloseVrDevice(lua_State* L)
+{
+ CloseVrDevice();
+ return 0;
+}
+
+int lua_IsVrDeviceReady(lua_State* L)
+{
+ bool result = IsVrDeviceReady();
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_UpdateVrTracking(lua_State* L)
+{
+ UpdateVrTracking();
+ return 0;
+}
+
+int lua_ToggleVrMode(lua_State* L)
+{
+ ToggleVrMode();
+ return 0;
+}
+
+//------------------------------------------------------------------------------------
+// raylib [audio] module functions - Audio Loading and Playing
+//------------------------------------------------------------------------------------
+int lua_InitAudioDevice(lua_State* L)
+{
+ InitAudioDevice();
+ return 0;
+}
+
+int lua_CloseAudioDevice(lua_State* L)
+{
+ CloseAudioDevice();
+ return 0;
+}
+
+int lua_IsAudioDeviceReady(lua_State* L)
+{
+ bool result = IsAudioDeviceReady();
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_LoadSound(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ Sound result = LoadSound((char*)arg1);
+ LuaPush_Sound(L, result);
+ return 1;
+}
+
+int lua_LoadSoundFromWave(lua_State* L)
+{
+ Wave arg1 = LuaGetArgument_Wave(L, 1);
+ Sound result = LoadSoundFromWave(arg1);
+ LuaPush_Sound(L, result);
+ return 1;
+}
+
+int lua_LoadSoundFromRES(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ Sound result = LoadSoundFromRES(arg1, arg2);
+ LuaPush_Sound(L, result);
+ return 1;
+}
+
+int lua_UnloadSound(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ UnloadSound(arg1);
+ return 0;
+}
+
+int lua_PlaySound(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ PlaySound(arg1);
+ return 0;
+}
+
+int lua_PauseSound(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ PauseSound(arg1);
+ return 0;
+}
+
+int lua_ResumeSound(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ ResumeSound(arg1);
+ return 0;
+}
+
+int lua_StopSound(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ StopSound(arg1);
+ return 0;
+}
+
+int lua_IsSoundPlaying(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ bool result = IsSoundPlaying(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_SetSoundVolume(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ SetSoundVolume(arg1, arg2);
+ return 0;
+}
+
+int lua_SetSoundPitch(lua_State* L)
+{
+ Sound arg1 = LuaGetArgument_Sound(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ SetSoundPitch(arg1, arg2);
+ return 0;
+}
+
+int lua_LoadMusicStream(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ Music result = LoadMusicStream((char *)arg1);
+ LuaPush_Music(L, result);
+ return 1;
+}
+
+int lua_UnloadMusicStream(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ UnloadMusicStream(arg1);
+ return 0;
+}
+
+int lua_UpdateMusicStream(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ UpdateMusicStream(arg1);
+ return 0;
+}
+
+int lua_PlayMusicStream(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ PlayMusicStream(arg1);
+ return 0;
+}
+
+
+int lua_StopMusicStream(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ StopMusicStream(arg1);
+ return 0;
+}
+
+int lua_PauseMusicStream(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ PauseMusicStream(arg1);
+ return 0;
+}
+
+int lua_ResumeMusicStream(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ ResumeMusicStream(arg1);
+ return 0;
+}
+
+int lua_IsMusicPlaying(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ bool result = IsMusicPlaying(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_SetMusicVolume(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ SetMusicVolume(arg1, arg2);
+ return 0;
+}
+
+int lua_SetMusicPitch(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ SetMusicPitch(arg1, arg2);
+ return 0;
+}
+
+int lua_GetMusicTimeLength(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ float result = GetMusicTimeLength(arg1);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_GetMusicTimePlayed(lua_State* L)
+{
+ Music arg1 = LuaGetArgument_Music(L, 1);
+ float result = GetMusicTimePlayed(arg1);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_InitAudioStream(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int arg2 = LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ AudioStream result = InitAudioStream(arg1, arg2, arg3);
+ LuaPush_AudioStream(L, result);
+ return 1;
+}
+
+int lua_CloseAudioStream(lua_State* L)
+{
+ AudioStream arg1 = LuaGetArgument_AudioStream(L, 1);
+ CloseAudioStream(arg1);
+ return 0;
+}
+
+int lua_UpdateAudioStream(lua_State* L)
+{
+ AudioStream arg1 = LuaGetArgument_AudioStream(L, 1);
+ void * arg2 = (char *)LuaGetArgument_string(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ UpdateAudioStream(arg1, arg2, arg3);
+ return 0;
+}
+
+int lua_IsAudioBufferProcessed(lua_State* L)
+{
+ AudioStream arg1 = LuaGetArgument_AudioStream(L, 1);
+ bool result = IsAudioBufferProcessed(arg1);
+ lua_pushboolean(L, result);
+ return 1;
+}
+
+int lua_PlayAudioStream(lua_State* L)
+{
+ AudioStream arg1 = LuaGetArgument_AudioStream(L, 1);
+ PlayAudioStream(arg1);
+ return 0;
+}
+
+
+int lua_StopAudioStream(lua_State* L)
+{
+ AudioStream arg1 = LuaGetArgument_AudioStream(L, 1);
+ StopAudioStream(arg1);
+ return 0;
+}
+
+int lua_PauseAudioStream(lua_State* L)
+{
+ AudioStream arg1 = LuaGetArgument_AudioStream(L, 1);
+ PauseAudioStream(arg1);
+ return 0;
+}
+
+int lua_ResumeAudioStream(lua_State* L)
+{
+ AudioStream arg1 = LuaGetArgument_AudioStream(L, 1);
+ ResumeAudioStream(arg1);
+ return 0;
+}
+
+//----------------------------------------------------------------------------------
+// raylib [utils] module functions
+//----------------------------------------------------------------------------------
+int lua_DecompressData(lua_State* L)
+{
+ unsigned char *arg1 = (unsigned char *)LuaGetArgument_string(L, 1);
+ unsigned arg2 = (unsigned)LuaGetArgument_int(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ unsigned char *result = DecompressData(arg1, arg2, arg3);
+ lua_pushlstring(L, (const char *)result, arg3);
+ return 1;
+}
+
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+int lua_WriteBitmap(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ unsigned char* arg2 = (unsigned char*)LuaGetArgument_string(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ WriteBitmap(arg1, arg2, arg3, arg4);
+ return 0;
+}
+
+int lua_WritePNG(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ unsigned char* arg2 = (unsigned char*)LuaGetArgument_string(L, 2);
+ int arg3 = LuaGetArgument_int(L, 3);
+ int arg4 = LuaGetArgument_int(L, 4);
+ int arg5 = LuaGetArgument_int(L, 5);
+ WritePNG(arg1, arg2, arg3, arg4, arg5);
+ return 0;
+}
+#endif
+
+int lua_TraceLog(lua_State* L)
+{
+ int num_args = lua_gettop(L) - 1;
+ int arg1 = LuaGetArgument_int(L, 1);
+
+ /// type, fmt, args...
+
+ lua_rotate(L, 1, -1); /// fmt, args..., type
+ lua_pop(L, 1); /// fmt, args...
+
+ lua_getglobal(L, "string"); /// fmt, args..., [string]
+ lua_getfield(L, 1, "format"); /// fmt, args..., [string], format()
+ lua_rotate(L, 1, 2); /// [string], format(), fmt, args...
+ lua_call(L, num_args, 1); /// [string], formatted_string
+
+ TraceLog(arg1, "%s", luaL_checkstring(L,-1));
+ return 0;
+}
+
+int lua_GetExtension(lua_State* L)
+{
+ const char * arg1 = LuaGetArgument_string(L, 1);
+ const char* result = GetExtension(arg1);
+ lua_pushstring(L, result);
+ return 1;
+}
+
+int lua_GetNextPOT(lua_State* L)
+{
+ int arg1 = LuaGetArgument_int(L, 1);
+ int result = GetNextPOT(arg1);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
+//----------------------------------------------------------------------------------
+// raylib [raymath] module functions - Vector3 math
+//----------------------------------------------------------------------------------
+int lua_VectorAdd(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 result = VectorAdd(arg1, arg2);
+ LuaPush_Vector3(L, result);
+ return 1;
+}
+
+int lua_VectorSubtract(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 result = VectorSubtract(arg1, arg2);
+ LuaPush_Vector3(L, result);
+ return 1;
+}
+
+int lua_VectorCrossProduct(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 result = VectorCrossProduct(arg1, arg2);
+ LuaPush_Vector3(L, result);
+ return 1;
+}
+
+int lua_VectorPerpendicular(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 result = VectorPerpendicular(arg1);
+ LuaPush_Vector3(L, result);
+ return 1;
+}
+
+int lua_VectorDotProduct(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float result = VectorDotProduct(arg1, arg2);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_VectorLength(lua_State* L)
+{
+ const Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float result = VectorLength(arg1);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_VectorScale(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ VectorScale(&arg1, arg2);
+ LuaPush_Vector3(L, arg1);
+ return 1;
+}
+
+int lua_VectorNegate(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ VectorNegate(&arg1);
+ LuaPush_Vector3(L, arg1);
+ return 1;
+}
+
+int lua_VectorNormalize(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ VectorNormalize(&arg1);
+ LuaPush_Vector3(L, arg1);
+ return 1;
+}
+
+int lua_VectorDistance(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float result = VectorDistance(arg1, arg2);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_VectorLerp(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Vector3 result = VectorLerp(arg1, arg2, arg3);
+ LuaPush_Vector3(L, result);
+ return 1;
+}
+
+int lua_VectorReflect(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 result = VectorReflect(arg1, arg2);
+ LuaPush_Vector3(L, result);
+ return 1;
+}
+
+int lua_VectorTransform(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+ VectorTransform(&arg1, arg2);
+ LuaPush_Vector3(L, arg1);
+ return 1;
+}
+
+int lua_VectorZero(lua_State* L)
+{
+ Vector3 result = VectorZero();
+ LuaPush_Vector3(L, result);
+ return 1;
+}
+
+//----------------------------------------------------------------------------------
+// raylib [raymath] module functions - Matrix math
+//----------------------------------------------------------------------------------
+int lua_MatrixDeterminant(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ float result = MatrixDeterminant(arg1);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_MatrixTrace(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ float result = MatrixTrace(arg1);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_MatrixTranspose(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ MatrixTranspose(&arg1);
+ LuaPush_Matrix(L, &arg1);
+ return 1;
+}
+
+int lua_MatrixInvert(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ MatrixInvert(&arg1);
+ LuaPush_Matrix(L, &arg1);
+ return 1;
+}
+
+int lua_MatrixNormalize(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ MatrixNormalize(&arg1);
+ LuaPush_Matrix(L, &arg1);
+ return 1;
+}
+
+int lua_MatrixIdentity(lua_State* L)
+{
+ Matrix result = MatrixIdentity();
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixAdd(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+ Matrix result = MatrixAdd(arg1, arg2);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixSubstract(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+ Matrix result = MatrixSubstract(arg1, arg2);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixTranslate(lua_State* L)
+{
+ float arg1 = LuaGetArgument_float(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Matrix result = MatrixTranslate(arg1, arg2, arg3);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixRotate(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Matrix result = MatrixRotate(arg1, arg2);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixRotateX(lua_State* L)
+{
+ float arg1 = LuaGetArgument_float(L, 1);
+ Matrix result = MatrixRotateX(arg1);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixRotateY(lua_State* L)
+{
+ float arg1 = LuaGetArgument_float(L, 1);
+ Matrix result = MatrixRotateY(arg1);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixRotateZ(lua_State* L)
+{
+ float arg1 = LuaGetArgument_float(L, 1);
+ Matrix result = MatrixRotateZ(arg1);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixScale(lua_State* L)
+{
+ float arg1 = LuaGetArgument_float(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Matrix result = MatrixScale(arg1, arg2, arg3);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixMultiply(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+ Matrix result = MatrixMultiply(arg1, arg2);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixFrustum(lua_State* L)
+{
+ double arg1 = LuaGetArgument_double(L, 1);
+ double arg2 = LuaGetArgument_double(L, 2);
+ double arg3 = LuaGetArgument_double(L, 3);
+ double arg4 = LuaGetArgument_double(L, 4);
+ double arg5 = LuaGetArgument_double(L, 5);
+ double arg6 = LuaGetArgument_double(L, 6);
+ Matrix result = MatrixFrustum(arg1, arg2, arg3, arg4, arg5, arg6);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixPerspective(lua_State* L)
+{
+ double arg1 = LuaGetArgument_double(L, 1);
+ double arg2 = LuaGetArgument_double(L, 2);
+ double arg3 = LuaGetArgument_double(L, 3);
+ double arg4 = LuaGetArgument_double(L, 4);
+ Matrix result = MatrixPerspective(arg1, arg2, arg3, arg4);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixOrtho(lua_State* L)
+{
+ double arg1 = LuaGetArgument_double(L, 1);
+ double arg2 = LuaGetArgument_double(L, 2);
+ double arg3 = LuaGetArgument_double(L, 3);
+ double arg4 = LuaGetArgument_double(L, 4);
+ double arg5 = LuaGetArgument_double(L, 5);
+ double arg6 = LuaGetArgument_double(L, 6);
+ Matrix result = MatrixOrtho(arg1, arg2, arg3, arg4, arg5, arg6);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_MatrixLookAt(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ Vector3 arg2 = LuaGetArgument_Vector3(L, 2);
+ Vector3 arg3 = LuaGetArgument_Vector3(L, 3);
+ Matrix result = MatrixLookAt(arg1, arg2, arg3);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+//----------------------------------------------------------------------------------
+// raylib [raymath] module functions - Quaternion math
+//----------------------------------------------------------------------------------
+int lua_QuaternionLength(lua_State* L)
+{
+ Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+ float result = QuaternionLength(arg1);
+ lua_pushnumber(L, result);
+ return 1;
+}
+
+int lua_QuaternionNormalize(lua_State* L)
+{
+ Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+ QuaternionNormalize(&arg1);
+ LuaPush_Quaternion(L, arg1);
+ return 1;
+}
+
+int lua_QuaternionMultiply(lua_State* L)
+{
+ Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+ Quaternion arg2 = LuaGetArgument_Quaternion(L, 2);
+ Quaternion result = QuaternionMultiply(arg1, arg2);
+ LuaPush_Quaternion(L, result);
+ return 1;
+}
+
+int lua_QuaternionSlerp(lua_State* L)
+{
+ Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+ Quaternion arg2 = LuaGetArgument_Quaternion(L, 2);
+ float arg3 = LuaGetArgument_float(L, 3);
+ Quaternion result = QuaternionSlerp(arg1, arg2, arg3);
+ LuaPush_Quaternion(L, result);
+ return 1;
+}
+
+int lua_QuaternionFromMatrix(lua_State* L)
+{
+ Matrix arg1 = LuaGetArgument_Matrix(L, 1);
+ Quaternion result = QuaternionFromMatrix(arg1);
+ LuaPush_Quaternion(L, result);
+ return 1;
+}
+
+int lua_QuaternionToMatrix(lua_State* L)
+{
+ Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+ Matrix result = QuaternionToMatrix(arg1);
+ LuaPush_Matrix(L, &result);
+ return 1;
+}
+
+int lua_QuaternionFromAxisAngle(lua_State* L)
+{
+ Vector3 arg1 = LuaGetArgument_Vector3(L, 1);
+ float arg2 = LuaGetArgument_float(L, 2);
+ Quaternion result = QuaternionFromAxisAngle(arg1, arg2);
+ LuaPush_Quaternion(L, result);
+ return 1;
+}
+
+int lua_QuaternionToAxisAngle(lua_State* L)
+{
+ Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+ Vector3 arg2;
+ float arg3 = 0;
+ QuaternionToAxisAngle(arg1, &arg2, &arg3);
+ LuaPush_Vector3(L, arg2);
+ lua_pushnumber(L, arg3);
+ return 2;
+}
+
+int lua_QuaternionTransform(lua_State* L)
+{
+ Quaternion arg1 = LuaGetArgument_Quaternion(L, 1);
+ Matrix arg2 = LuaGetArgument_Matrix(L, 2);
+ QuaternionTransform(&arg1, arg2);
+ LuaPush_Quaternion(L, arg1);
+ return 1;
+}
+
+
+//----------------------------------------------------------------------------------
+// Functions Registering
+//----------------------------------------------------------------------------------
+#define REG(name) { #name, lua_##name },
+
+// raylib Functions (and data types) list
+static luaL_Reg raylib_functions[] = {
+
+ // Register non-opaque data types
+ REG(Color)
+ REG(Vector2)
+ REG(Vector3)
+ //REG(Matrix)
+ REG(Quaternion)
+ REG(Rectangle)
+ REG(Ray)
+ REG(Camera)
+ REG(Camera2D)
+ REG(BoundingBox)
+ //REG(Material)
+
+ // Register functions
+ REG(InitWindow)
+ REG(CloseWindow)
+ REG(WindowShouldClose)
+ REG(IsWindowMinimized)
+ REG(ToggleFullscreen)
+ REG(GetScreenWidth)
+ REG(GetScreenHeight)
+
+ REG(ShowCursor)
+ REG(HideCursor)
+ REG(IsCursorHidden)
+ REG(EnableCursor)
+ REG(DisableCursor)
+
+ REG(ClearBackground)
+ REG(BeginDrawing)
+ REG(EndDrawing)
+ REG(Begin2dMode)
+ REG(End2dMode)
+ REG(Begin3dMode)
+ REG(End3dMode)
+ REG(BeginTextureMode)
+ REG(EndTextureMode)
+
+ REG(GetMouseRay)
+ REG(GetWorldToScreen)
+ REG(GetCameraMatrix)
+
+#if defined(PLATFORM_WEB)
+ REG(SetDrawingLoop)
+#else
+ REG(SetTargetFPS)
+#endif
+ REG(GetFPS)
+ REG(GetFrameTime)
+
+ REG(GetColor)
+ REG(GetHexValue)
+ REG(ColorToFloat)
+ REG(VectorToFloat)
+ REG(MatrixToFloat)
+ REG(GetRandomValue)
+ REG(Fade)
+ REG(SetConfigFlags)
+ REG(ShowLogo)
+
+ REG(IsFileDropped)
+ REG(GetDroppedFiles)
+ REG(ClearDroppedFiles)
+ REG(StorageSaveValue)
+ REG(StorageLoadValue)
+
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
+ REG(IsKeyPressed)
+ REG(IsKeyDown)
+ REG(IsKeyReleased)
+ REG(IsKeyUp)
+ REG(GetKeyPressed)
+ REG(SetExitKey)
+
+ REG(IsGamepadAvailable)
+ REG(GetGamepadAxisMovement)
+ REG(IsGamepadButtonPressed)
+ REG(IsGamepadButtonDown)
+ REG(IsGamepadButtonReleased)
+ REG(IsGamepadButtonUp)
+#endif
+
+ REG(IsMouseButtonPressed)
+ REG(IsMouseButtonDown)
+ REG(IsMouseButtonReleased)
+ REG(IsMouseButtonUp)
+ REG(GetMouseX)
+ REG(GetMouseY)
+ REG(GetMousePosition)
+ REG(SetMousePosition)
+ REG(GetMouseWheelMove)
+ REG(GetTouchX)
+ REG(GetTouchY)
+ REG(GetTouchPosition)
+
+#if defined(PLATFORM_ANDROID)
+ REG(IsButtonPressed)
+ REG(IsButtonDown)
+ REG(IsButtonReleased)
+#endif
+
+ REG(SetGesturesEnabled)
+ REG(IsGestureDetected)
+ REG(GetGestureDetected)
+ REG(GetTouchPointsCount)
+ REG(GetGestureHoldDuration)
+ REG(GetGestureDragVector)
+ REG(GetGestureDragAngle)
+ REG(GetGesturePinchVector)
+ REG(GetGesturePinchAngle)
+
+ REG(SetCameraMode)
+ REG(UpdateCamera)
+ REG(UpdateCameraPlayer)
+ REG(SetCameraPosition)
+ REG(SetCameraTarget)
+ REG(SetCameraFovy)
+
+ REG(SetCameraPanControl)
+ REG(SetCameraAltControl)
+ REG(SetCameraSmoothZoomControl)
+ REG(SetCameraMoveControls)
+ REG(SetCameraMouseSensitivity)
+
+ REG(DrawPixel)
+ REG(DrawPixelV)
+ REG(DrawLine)
+ REG(DrawLineV)
+ REG(DrawCircle)
+ REG(DrawCircleGradient)
+ REG(DrawCircleV)
+ REG(DrawCircleLines)
+ REG(DrawRectangle)
+ REG(DrawRectangleRec)
+ REG(DrawRectangleGradient)
+ REG(DrawRectangleV)
+ REG(DrawRectangleLines)
+ REG(DrawTriangle)
+ REG(DrawTriangleLines)
+ REG(DrawPoly)
+ REG(DrawPolyEx)
+ REG(DrawPolyExLines)
+
+ REG(CheckCollisionRecs)
+ REG(CheckCollisionCircles)
+ REG(CheckCollisionCircleRec)
+ REG(GetCollisionRec)
+ REG(CheckCollisionPointRec)
+ REG(CheckCollisionPointCircle)
+ REG(CheckCollisionPointTriangle)
+
+ REG(LoadImage)
+ REG(LoadImageEx)
+ REG(LoadImageRaw)
+ REG(LoadImageFromRES)
+ REG(LoadTexture)
+ REG(LoadTextureEx)
+ REG(LoadTextureFromRES)
+ REG(LoadTextureFromImage)
+ REG(LoadRenderTexture)
+ REG(UnloadImage)
+ REG(UnloadTexture)
+ REG(UnloadRenderTexture)
+ REG(GetImageData)
+ REG(GetTextureData)
+ REG(ImageToPOT)
+ REG(ImageFormat)
+ REG(ImageDither)
+ REG(ImageCopy)
+ REG(ImageCrop)
+ REG(ImageResize)
+ REG(ImageResizeNN)
+ REG(ImageText)
+ REG(ImageTextEx)
+ REG(ImageDraw)
+ REG(ImageDrawText)
+ REG(ImageDrawTextEx)
+ REG(ImageFlipVertical)
+ REG(ImageFlipHorizontal)
+ REG(ImageColorTint)
+ REG(ImageColorInvert)
+ REG(ImageColorGrayscale)
+ REG(ImageColorContrast)
+ REG(ImageColorBrightness)
+ REG(GenTextureMipmaps)
+ REG(UpdateTexture)
+
+ REG(DrawTexture)
+ REG(DrawTextureV)
+ REG(DrawTextureEx)
+ REG(DrawTextureRec)
+ REG(DrawTexturePro)
+
+ REG(GetDefaultFont)
+ REG(LoadSpriteFont)
+ REG(UnloadSpriteFont)
+ REG(DrawText)
+ REG(DrawTextEx)
+ REG(MeasureText)
+ REG(MeasureTextEx)
+ REG(DrawFPS)
+
+ REG(DrawLine3D)
+ REG(DrawCircle3D)
+ REG(DrawCube)
+ REG(DrawCubeV)
+ REG(DrawCubeWires)
+ REG(DrawCubeTexture)
+ REG(DrawSphere)
+ REG(DrawSphereEx)
+ REG(DrawSphereWires)
+ REG(DrawCylinder)
+ REG(DrawCylinderWires)
+ REG(DrawPlane)
+ REG(DrawRay)
+ REG(DrawGrid)
+ REG(DrawGizmo)
+ REG(DrawLight)
+
+ REG(LoadModel)
+ REG(LoadModelEx)
+ REG(LoadModelFromRES)
+ REG(LoadHeightmap)
+ REG(LoadCubicmap)
+ REG(UnloadModel)
+ REG(LoadMaterial)
+ REG(LoadDefaultMaterial)
+ REG(LoadStandardMaterial)
+ REG(UnloadMaterial)
+ //REG(GenMesh*) // Not ready yet...
+
+ REG(DrawModel)
+ REG(DrawModelEx)
+ REG(DrawModelWires)
+ REG(DrawModelWiresEx)
+ REG(DrawBillboard)
+ REG(DrawBillboardRec)
+ REG(CalculateBoundingBox)
+ REG(CheckCollisionSpheres)
+ REG(CheckCollisionBoxes)
+ REG(CheckCollisionBoxSphere)
+ REG(CheckCollisionRaySphere)
+ REG(CheckCollisionRaySphereEx)
+ REG(CheckCollisionRayBox)
+ REG(ResolveCollisionCubicmap)
+
+ REG(LoadShader)
+ REG(UnloadShader)
+ REG(GetDefaultShader)
+ REG(GetStandardShader)
+ REG(GetDefaultTexture)
+ REG(GetShaderLocation)
+ REG(SetShaderValue)
+ REG(SetShaderValuei)
+ REG(SetShaderValueMatrix)
+ REG(SetMatrixProjection)
+ REG(SetMatrixModelview)
+ REG(BeginShaderMode)
+ REG(EndShaderMode)
+ REG(BeginBlendMode)
+ REG(EndBlendMode)
+ REG(CreateLight)
+ REG(DestroyLight)
+
+ REG(InitVrDevice)
+ REG(CloseVrDevice)
+ REG(IsVrDeviceReady)
+ REG(UpdateVrTracking)
+ REG(ToggleVrMode)
+
+ REG(InitAudioDevice)
+ REG(CloseAudioDevice)
+ REG(IsAudioDeviceReady)
+ REG(LoadSound)
+ REG(LoadSoundFromWave)
+ REG(LoadSoundFromRES)
+ REG(UnloadSound)
+ REG(PlaySound)
+ REG(PauseSound)
+ REG(ResumeSound)
+ REG(StopSound)
+ REG(IsSoundPlaying)
+ REG(SetSoundVolume)
+ REG(SetSoundPitch)
+
+ REG(LoadMusicStream)
+ REG(UnloadMusicStream)
+ REG(UpdateMusicStream)
+ REG(PlayMusicStream)
+ REG(StopMusicStream)
+ REG(PauseMusicStream)
+ REG(ResumeMusicStream)
+ REG(IsMusicPlaying)
+ REG(SetMusicVolume)
+ REG(SetMusicPitch)
+ REG(GetMusicTimeLength)
+ REG(GetMusicTimePlayed)
+
+ REG(InitAudioStream)
+ REG(UpdateAudioStream)
+ REG(CloseAudioStream)
+ REG(IsAudioBufferProcessed)
+ REG(PlayAudioStream)
+ REG(PauseAudioStream)
+ REG(ResumeAudioStream)
+ REG(StopAudioStream)
+
+ /// Math and util
+ REG(DecompressData)
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+ REG(WriteBitmap)
+ REG(WritePNG)
+#endif
+ REG(TraceLog)
+ REG(GetExtension)
+ REG(GetNextPOT)
+ REG(VectorAdd)
+ REG(VectorSubtract)
+ REG(VectorCrossProduct)
+ REG(VectorPerpendicular)
+ REG(VectorDotProduct)
+ REG(VectorLength)
+ REG(VectorScale)
+ REG(VectorNegate)
+ REG(VectorNormalize)
+ REG(VectorDistance)
+ REG(VectorLerp)
+ REG(VectorReflect)
+ REG(VectorTransform)
+ REG(VectorZero)
+ REG(MatrixDeterminant)
+ REG(MatrixTrace)
+ REG(MatrixTranspose)
+ REG(MatrixInvert)
+ REG(MatrixNormalize)
+ REG(MatrixIdentity)
+ REG(MatrixAdd)
+ REG(MatrixSubstract)
+ REG(MatrixTranslate)
+ REG(MatrixRotate)
+ REG(MatrixRotateX)
+ REG(MatrixRotateY)
+ REG(MatrixRotateZ)
+ REG(MatrixScale)
+ REG(MatrixMultiply)
+ REG(MatrixFrustum)
+ REG(MatrixPerspective)
+ REG(MatrixOrtho)
+ REG(MatrixLookAt)
+ REG(QuaternionLength)
+ REG(QuaternionNormalize)
+ REG(QuaternionMultiply)
+ REG(QuaternionSlerp)
+ REG(QuaternionFromMatrix)
+ REG(QuaternionToMatrix)
+ REG(QuaternionFromAxisAngle)
+ REG(QuaternionToAxisAngle)
+ REG(QuaternionTransform)
+
+ {NULL, NULL} // sentinel: end signal
+};
+
+// Register raylib functionality
+static void LuaRegisterRayLib(const char *opt_table)
+{
+ if (opt_table) lua_createtable(L, 0, sizeof(raylib_functions)/sizeof(raylib_functions[0]));
+ else lua_pushglobaltable(L);
+
+ luaL_setfuncs(L, raylib_functions, 0);
+}
+
+//----------------------------------------------------------------------------------
+// raylib Lua API
+//----------------------------------------------------------------------------------
+
+// Initialize Lua system
+RLUADEF void InitLuaDevice(void)
+{
+ mainLuaState = luaL_newstate();
+ L = mainLuaState;
+
+ LuaStartEnum();
+ LuaSetEnum("FULLSCREEN_MODE", 1);
+ LuaSetEnum("SHOW_LOGO", 2);
+ LuaSetEnum("SHOW_MOUSE_CURSOR", 4);
+ LuaSetEnum("CENTERED_MODE", 8);
+ LuaSetEnum("MSAA_4X_HINT", 16);
+ LuaSetEnum("VSYNC_HINT", 32);
+ LuaEndEnum("FLAG");
+
+ LuaStartEnum();
+ LuaSetEnum("SPACE", 32);
+ LuaSetEnum("ESCAPE", 256);
+ LuaSetEnum("ENTER", 257);
+ LuaSetEnum("BACKSPACE", 259);
+ LuaSetEnum("RIGHT", 262);
+ LuaSetEnum("LEFT", 263);
+ LuaSetEnum("DOWN", 264);
+ LuaSetEnum("UP", 265);
+ LuaSetEnum("F1", 290);
+ LuaSetEnum("F2", 291);
+ LuaSetEnum("F3", 292);
+ LuaSetEnum("F4", 293);
+ LuaSetEnum("F5", 294);
+ LuaSetEnum("F6", 295);
+ LuaSetEnum("F7", 296);
+ LuaSetEnum("F8", 297);
+ LuaSetEnum("F9", 298);
+ LuaSetEnum("F10", 299);
+ LuaSetEnum("LEFT_SHIFT", 340);
+ LuaSetEnum("LEFT_CONTROL", 341);
+ LuaSetEnum("LEFT_ALT", 342);
+ LuaSetEnum("RIGHT_SHIFT", 344);
+ LuaSetEnum("RIGHT_CONTROL", 345);
+ LuaSetEnum("RIGHT_ALT", 346);
+ LuaSetEnum("ZERO", 48);
+ LuaSetEnum("ONE", 49);
+ LuaSetEnum("TWO", 50);
+ LuaSetEnum("THREE", 51);
+ LuaSetEnum("FOUR", 52);
+ LuaSetEnum("FIVE", 53);
+ LuaSetEnum("SIX", 54);
+ LuaSetEnum("SEVEN", 55);
+ LuaSetEnum("EIGHT", 56);
+ LuaSetEnum("NINE", 57);
+ LuaSetEnum("A", 65);
+ LuaSetEnum("B", 66);
+ LuaSetEnum("C", 67);
+ LuaSetEnum("D", 68);
+ LuaSetEnum("E", 69);
+ LuaSetEnum("F", 70);
+ LuaSetEnum("G", 71);
+ LuaSetEnum("H", 72);
+ LuaSetEnum("I", 73);
+ LuaSetEnum("J", 74);
+ LuaSetEnum("K", 75);
+ LuaSetEnum("L", 76);
+ LuaSetEnum("M", 77);
+ LuaSetEnum("N", 78);
+ LuaSetEnum("O", 79);
+ LuaSetEnum("P", 80);
+ LuaSetEnum("Q", 81);
+ LuaSetEnum("R", 82);
+ LuaSetEnum("S", 83);
+ LuaSetEnum("T", 84);
+ LuaSetEnum("U", 85);
+ LuaSetEnum("V", 86);
+ LuaSetEnum("W", 87);
+ LuaSetEnum("X", 88);
+ LuaSetEnum("Y", 89);
+ LuaSetEnum("Z", 90);
+ LuaEndEnum("KEY");
+
+ LuaStartEnum();
+ LuaSetEnum("LEFT_BUTTON", 0);
+ LuaSetEnum("RIGHT_BUTTON", 1);
+ LuaSetEnum("MIDDLE_BUTTON", 2);
+ LuaEndEnum("MOUSE");
+
+ LuaStartEnum();
+ LuaSetEnum("PLAYER1", 0);
+ LuaSetEnum("PLAYER2", 1);
+ LuaSetEnum("PLAYER3", 2);
+ LuaSetEnum("PLAYER4", 3);
+
+ LuaSetEnum("PS3_BUTTON_A", 2);
+ LuaSetEnum("PS3_BUTTON_B", 1);
+ LuaSetEnum("PS3_BUTTON_X", 3);
+ LuaSetEnum("PS3_BUTTON_Y", 4);
+ LuaSetEnum("PS3_BUTTON_R1", 7);
+ LuaSetEnum("PS3_BUTTON_R2", 5);
+ LuaSetEnum("PS3_BUTTON_L1", 6);
+ LuaSetEnum("PS3_BUTTON_L2", 8);
+ LuaSetEnum("PS3_BUTTON_SELECT", 9);
+ LuaSetEnum("PS3_BUTTON_START", 10);
+
+ LuaSetEnum("XBOX_BUTTON_A", 0);
+ LuaSetEnum("XBOX_BUTTON_B", 1);
+ LuaSetEnum("XBOX_BUTTON_X", 2);
+ LuaSetEnum("XBOX_BUTTON_Y", 3);
+ LuaSetEnum("XBOX_BUTTON_LB", 4);
+ LuaSetEnum("XBOX_BUTTON_RB", 5);
+ LuaSetEnum("XBOX_BUTTON_SELECT", 6);
+ LuaSetEnum("XBOX_BUTTON_START", 7);
+
+#if defined(PLATFORM_RPI)
+ LuaSetEnum("XBOX_AXIS_DPAD_X", 7);
+ LuaSetEnum("XBOX_AXIS_DPAD_Y", 6);
+ LuaSetEnum("XBOX_AXIS_RIGHT_X", 3);
+ LuaSetEnum("XBOX_AXIS_RIGHT_Y", 4);
+ LuaSetEnum("XBOX_AXIS_LT", 2);
+ LuaSetEnum("XBOX_AXIS_RT", 5);
+#else
+ LuaSetEnum("XBOX_BUTTON_UP", 10);
+ LuaSetEnum("XBOX_BUTTON_DOWN", 12);
+ LuaSetEnum("XBOX_BUTTON_LEFT", 13);
+ LuaSetEnum("XBOX_BUTTON_RIGHT", 11);
+ LuaSetEnum("XBOX_AXIS_RIGHT_X", 4);
+ LuaSetEnum("XBOX_AXIS_RIGHT_Y", 3);
+ LuaSetEnum("XBOX_AXIS_LT_RT", 2);
+#endif
+ LuaSetEnum("XBOX_AXIS_LEFT_X", 0);
+ LuaSetEnum("XBOX_AXIS_LEFT_Y", 1);
+ LuaEndEnum("GAMEPAD");
+
+ lua_pushglobaltable(L);
+ LuaSetEnumColor("LIGHTGRAY", LIGHTGRAY);
+ LuaSetEnumColor("GRAY", GRAY);
+ LuaSetEnumColor("DARKGRAY", DARKGRAY);
+ LuaSetEnumColor("YELLOW", YELLOW);
+ LuaSetEnumColor("GOLD", GOLD);
+ LuaSetEnumColor("ORANGE", ORANGE);
+ LuaSetEnumColor("PINK", PINK);
+ LuaSetEnumColor("RED", RED);
+ LuaSetEnumColor("MAROON", MAROON);
+ LuaSetEnumColor("GREEN", GREEN);
+ LuaSetEnumColor("LIME", LIME);
+ LuaSetEnumColor("DARKGREEN", DARKGREEN);
+ LuaSetEnumColor("SKYBLUE", SKYBLUE);
+ LuaSetEnumColor("BLUE", BLUE);
+ LuaSetEnumColor("DARKBLUE", DARKBLUE);
+ LuaSetEnumColor("PURPLE", PURPLE);
+ LuaSetEnumColor("VIOLET", VIOLET);
+ LuaSetEnumColor("DARKPURPLE", DARKPURPLE);
+ LuaSetEnumColor("BEIGE", BEIGE);
+ LuaSetEnumColor("BROWN", BROWN);
+ LuaSetEnumColor("DARKBROWN", DARKBROWN);
+ LuaSetEnumColor("WHITE", WHITE);
+ LuaSetEnumColor("BLACK", BLACK);
+ LuaSetEnumColor("BLANK", BLANK);
+ LuaSetEnumColor("MAGENTA", MAGENTA);
+ LuaSetEnumColor("RAYWHITE", RAYWHITE);
+ lua_pop(L, 1);
+
+ LuaStartEnum();
+ LuaSetEnum("UNCOMPRESSED_GRAYSCALE", UNCOMPRESSED_GRAYSCALE);
+ LuaSetEnum("UNCOMPRESSED_GRAY_ALPHA", UNCOMPRESSED_GRAY_ALPHA);
+ LuaSetEnum("UNCOMPRESSED_R5G6B5", UNCOMPRESSED_R5G6B5);
+ LuaSetEnum("UNCOMPRESSED_R8G8B8", UNCOMPRESSED_R8G8B8);
+ LuaSetEnum("UNCOMPRESSED_R5G5B5A1", UNCOMPRESSED_R5G5B5A1);
+ LuaSetEnum("UNCOMPRESSED_R4G4B4A4", UNCOMPRESSED_R4G4B4A4);
+ LuaSetEnum("UNCOMPRESSED_R8G8B8A8", UNCOMPRESSED_R8G8B8A8);
+ LuaSetEnum("COMPRESSED_DXT1_RGB", COMPRESSED_DXT1_RGB);
+ LuaSetEnum("COMPRESSED_DXT1_RGBA", COMPRESSED_DXT1_RGBA);
+ LuaSetEnum("COMPRESSED_DXT3_RGBA", COMPRESSED_DXT3_RGBA);
+ LuaSetEnum("COMPRESSED_DXT5_RGBA", COMPRESSED_DXT5_RGBA);
+ LuaSetEnum("COMPRESSED_ETC1_RGB", COMPRESSED_ETC1_RGB);
+ LuaSetEnum("COMPRESSED_ETC2_RGB", COMPRESSED_ETC2_RGB);
+ LuaSetEnum("COMPRESSED_ETC2_EAC_RGBA", COMPRESSED_ETC2_EAC_RGBA);
+ LuaSetEnum("COMPRESSED_PVRT_RGB", COMPRESSED_PVRT_RGB);
+ LuaSetEnum("COMPRESSED_PVRT_RGBA", COMPRESSED_PVRT_RGBA);
+ LuaSetEnum("COMPRESSED_ASTC_4x4_RGBA", COMPRESSED_ASTC_4x4_RGBA);
+ LuaSetEnum("COMPRESSED_ASTC_8x8_RGBA", COMPRESSED_ASTC_8x8_RGBA);
+ LuaEndEnum("TextureFormat");
+
+ LuaStartEnum();
+ LuaSetEnum("ALPHA", BLEND_ALPHA);
+ LuaSetEnum("ADDITIVE", BLEND_ADDITIVE);
+ LuaSetEnum("MULTIPLIED", BLEND_MULTIPLIED);
+ LuaEndEnum("BlendMode");
+
+ LuaStartEnum();
+ LuaSetEnum("POINT", LIGHT_POINT);
+ LuaSetEnum("DIRECTIONAL", LIGHT_DIRECTIONAL);
+ LuaSetEnum("SPOT", LIGHT_SPOT);
+ LuaEndEnum("LightType");
+
+ LuaStartEnum();
+ LuaSetEnum("NONE", GESTURE_NONE);
+ LuaSetEnum("TAP", GESTURE_TAP);
+ LuaSetEnum("DOUBLETAP", GESTURE_DOUBLETAP);
+ LuaSetEnum("HOLD", GESTURE_HOLD);
+ LuaSetEnum("DRAG", GESTURE_DRAG);
+ LuaSetEnum("SWIPE_RIGHT", GESTURE_SWIPE_RIGHT);
+ LuaSetEnum("SWIPE_LEFT", GESTURE_SWIPE_LEFT);
+ LuaSetEnum("SWIPE_UP", GESTURE_SWIPE_UP);
+ LuaSetEnum("SWIPE_DOWN", GESTURE_SWIPE_DOWN);
+ LuaSetEnum("PINCH_IN", GESTURE_PINCH_IN);
+ LuaSetEnum("PINCH_OUT", GESTURE_PINCH_OUT);
+ LuaEndEnum("Gestures");
+
+ LuaStartEnum();
+ LuaSetEnum("CUSTOM", CAMERA_CUSTOM);
+ LuaSetEnum("FREE", CAMERA_FREE);
+ LuaSetEnum("ORBITAL", CAMERA_ORBITAL);
+ LuaSetEnum("FIRST_PERSON", CAMERA_FIRST_PERSON);
+ LuaSetEnum("THIRD_PERSON", CAMERA_THIRD_PERSON);
+ LuaEndEnum("CameraMode");
+
+ LuaStartEnum();
+ LuaSetEnum("DEFAULT_DEVICE", HMD_DEFAULT_DEVICE);
+ LuaSetEnum("OCULUS_RIFT_DK2", HMD_OCULUS_RIFT_DK2);
+ LuaSetEnum("OCULUS_RIFT_CV1", HMD_OCULUS_RIFT_CV1);
+ LuaSetEnum("VALVE_HTC_VIVE", HMD_VALVE_HTC_VIVE);
+ LuaSetEnum("SAMSUNG_GEAR_VR", HMD_SAMSUNG_GEAR_VR);
+ LuaSetEnum("GOOGLE_CARDBOARD", HMD_GOOGLE_CARDBOARD);
+ LuaSetEnum("SONY_PLAYSTATION_VR", HMD_SONY_PLAYSTATION_VR);
+ LuaSetEnum("RAZER_OSVR", HMD_RAZER_OSVR);
+ LuaSetEnum("FOVE_VR", HMD_FOVE_VR);
+ LuaEndEnum("VrDevice");
+
+ lua_pushglobaltable(L);
+ LuaSetEnum("INFO", INFO);
+ LuaSetEnum("ERROR", ERROR);
+ LuaSetEnum("WARNING", WARNING);
+ LuaSetEnum("DEBUG", DEBUG);
+ LuaSetEnum("OTHER", OTHER);
+ lua_pop(L, 1);
+
+ lua_pushboolean(L, true);
+#if defined(PLATFORM_DESKTOP)
+ lua_setglobal(L, "PLATFORM_DESKTOP");
+#elif defined(PLATFORM_ANDROID)
+ lua_setglobal(L, "PLATFORM_ANDROID");
+#elif defined(PLATFORM_RPI)
+ lua_setglobal(L, "PLATFORM_RPI");
+#elif defined(PLATFORM_WEB)
+ lua_setglobal(L, "PLATFORM_WEB");
+#endif
+
+ luaL_openlibs(L);
+ LuaBuildOpaqueMetatables();
+
+ LuaRegisterRayLib(0);
+}
+
+// De-initialize Lua system
+RLUADEF void CloseLuaDevice(void)
+{
+ if (mainLuaState)
+ {
+ lua_close(mainLuaState);
+ mainLuaState = 0;
+ L = 0;
+ }
+}
+
+// Execute raylib Lua code
+RLUADEF void ExecuteLuaCode(const char *code)
+{
+ if (!mainLuaState)
+ {
+ TraceLog(WARNING, "Lua device not initialized");
+ return;
+ }
+
+ int result = luaL_dostring(L, code);
+
+ switch (result)
+ {
+ case LUA_OK: break;
+ case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1)); break;
+ case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1)); break;
+ default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1)); break;
+ }
+}
+
+// Execute raylib Lua script
+RLUADEF void ExecuteLuaFile(const char *filename)
+{
+ if (!mainLuaState)
+ {
+ TraceLog(WARNING, "Lua device not initialized");
+ return;
+ }
+
+ int result = luaL_dofile(L, filename);
+
+ switch (result)
+ {
+ case LUA_OK: break;
+ case LUA_ERRRUN: TraceLog(ERROR, "Lua Runtime Error: %s", lua_tostring(L, -1));
+ case LUA_ERRMEM: TraceLog(ERROR, "Lua Memory Error: %s", lua_tostring(L, -1));
+ default: TraceLog(ERROR, "Lua Error: %s", lua_tostring(L, -1));
+ }
+}
+
+#endif // RLUA_IMPLEMENTATION
diff --git a/src/shapes.c b/src/shapes.c
index d9b172f1..362dc0f7 100644
--- a/src/shapes.c
+++ b/src/shapes.c
@@ -113,7 +113,7 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
- rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius);
+ rlVertex2f(centerX + sin(DEG2RAD*(i + 10))*radius, centerY + cos(DEG2RAD*(i + 10))*radius);
}
rlEnd();
}
@@ -131,7 +131,7 @@ void DrawCircleV(Vector2 center, float radius, Color color)
rlVertex2i(center.x, center.y);
rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
- rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
+ rlVertex2f(center.x + sin(DEG2RAD*(i + 10))*radius, center.y + cos(DEG2RAD*(i + 10))*radius);
}
rlEnd();
}
@@ -146,8 +146,8 @@ void DrawCircleV(Vector2 center, float radius, Color color)
rlVertex2i(center.x, center.y);
rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
- rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
- rlVertex2f(center.x + sin(DEG2RAD*(i + 20)) * radius, center.y + cos(DEG2RAD*(i + 20)) * radius);
+ rlVertex2f(center.x + sin(DEG2RAD*(i + 10))*radius, center.y + cos(DEG2RAD*(i + 10))*radius);
+ rlVertex2f(center.x + sin(DEG2RAD*(i + 20))*radius, center.y + cos(DEG2RAD*(i + 20))*radius);
}
rlEnd();
@@ -165,7 +165,7 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
for (int i = 0; i < 360; i += 10)
{
rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
- rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius);
+ rlVertex2f(centerX + sin(DEG2RAD*(i + 10))*radius, centerY + cos(DEG2RAD*(i + 10))*radius);
}
rlEnd();
}
@@ -347,11 +347,11 @@ void DrawPolyEx(Vector2 *points, int numPoints, Color color)
rlBegin(RL_TRIANGLES);
rlColor4ub(color.r, color.g, color.b, color.a);
- for (int i = 0; i < numPoints - 2; i++)
+ for (int i = 1; i < numPoints - 1; i++)
{
+ rlVertex2f(points[0].x, points[0].y);
rlVertex2f(points[i].x, points[i].y);
rlVertex2f(points[i + 1].x, points[i + 1].y);
- rlVertex2f(points[i + 2].x, points[i + 2].y);
}
rlEnd();
}
diff --git a/src/text.c b/src/text.c
index ec2480e3..c538ea56 100644
--- a/src/text.c
+++ b/src/text.c
@@ -34,7 +34,7 @@
// Following libs are used on LoadTTF()
#define STB_TRUETYPE_IMPLEMENTATION
-#include "external/stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
+#include "external/stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
// Rectangle packing functions (not used at the moment)
//#define STB_RECT_PACK_IMPLEMENTATION
@@ -43,8 +43,7 @@
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define FONT_FIRST_CHAR 32
-#define MAX_FONTCHARS 128
+#define FONT_FIRST_CHAR 32 // NOTE: Expected first char for a sprite font
#define MAX_FORMATTEXT_LENGTH 64
#define MAX_SUBTEXT_LENGTH 64
@@ -72,7 +71,9 @@ static SpriteFont defaultFont; // Default font provided by raylib
static SpriteFont LoadImageFont(Image image, Color key, int firstChar); // Load a Image font file (XNA style)
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
-static SpriteFont LoadTTF(const char *fileName, int fontSize); // Generate a sprite font image from TTF data (font size required)
+
+// Generate a sprite font image from TTF data
+static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int numChars);
extern void LoadDefaultFont(void);
extern void UnloadDefaultFont(void);
@@ -150,7 +151,7 @@ extern void LoadDefaultFont(void)
//----------------------------------------------------------------------
int imWidth = 128;
int imHeight = 128;
-
+
Color *imagePixels = (Color *)malloc(imWidth*imHeight*sizeof(Color));
for (int i = 0; i < imWidth*imHeight; i++) imagePixels[i] = BLANK; // Initialize array
@@ -173,7 +174,7 @@ extern void LoadDefaultFont(void)
//FILE *myimage = fopen("default_font.raw", "wb");
//fwrite(image.pixels, 1, 128*128*4, myimage);
//fclose(myimage);
-
+
Image image = LoadImageEx(imagePixels, imWidth, imHeight);
ImageFormat(&image, UNCOMPRESSED_GRAY_ALPHA);
@@ -184,13 +185,13 @@ extern void LoadDefaultFont(void)
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
//------------------------------------------------------------------------------
- defaultFont.charValues = (int *)malloc(defaultFont.numChars*sizeof(int));
+ defaultFont.charValues = (int *)malloc(defaultFont.numChars*sizeof(int));
defaultFont.charRecs = (Rectangle *)malloc(defaultFont.numChars*sizeof(Rectangle)); // Allocate space for our character rectangle data
// This memory should be freed at end! --> Done on CloseWindow()
-
+
defaultFont.charOffsets = (Vector2 *)malloc(defaultFont.numChars*sizeof(Vector2));
defaultFont.charAdvanceX = (int *)malloc(defaultFont.numChars*sizeof(int));
-
+
int currentLine = 0;
int currentPosX = charsDivisor;
int testPosX = charsDivisor;
@@ -198,9 +199,9 @@ extern void LoadDefaultFont(void)
for (int i = 0; i < defaultFont.numChars; i++)
{
defaultFont.charValues[i] = FONT_FIRST_CHAR + i; // First char is 32
-
+
defaultFont.charRecs[i].x = currentPosX;
- defaultFont.charRecs[i].y = charsDivisor + currentLine * (charsHeight + charsDivisor);
+ defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor);
defaultFont.charRecs[i].width = charsWidth[i];
defaultFont.charRecs[i].height = charsHeight;
@@ -216,12 +217,12 @@ extern void LoadDefaultFont(void)
defaultFont.charRecs[i].y = charsDivisor + currentLine*(charsHeight + charsDivisor);
}
else currentPosX = testPosX;
-
+
// NOTE: On default font character offsets and xAdvance are not required
defaultFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f };
defaultFont.charAdvanceX[i] = 0;
}
-
+
defaultFont.size = defaultFont.charRecs[0].height;
TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id);
@@ -245,19 +246,23 @@ SpriteFont GetDefaultFont()
// Load a SpriteFont image into GPU memory
SpriteFont LoadSpriteFont(const char *fileName)
{
+ // Default hardcoded values for ttf file loading
+ #define DEFAULT_TTF_FONTSIZE 32 // Font first character (32 - space)
+ #define DEFAULT_TTF_NUMCHARS 95 // ASCII 32..126 is 95 glyphs
+
SpriteFont spriteFont = { 0 };
// Check file extension
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
- else if (strcmp(GetExtension(fileName),"ttf") == 0) spriteFont = LoadTTF(fileName, 32);
+ else if (strcmp(GetExtension(fileName),"ttf") == 0) spriteFont = LoadTTF(fileName, DEFAULT_TTF_FONTSIZE, FONT_FIRST_CHAR, DEFAULT_TTF_NUMCHARS);
else if (strcmp(GetExtension(fileName),"fnt") == 0) spriteFont = LoadBMFont(fileName);
else
{
Image image = LoadImage(fileName);
- if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, 32);
+ if (image.data != NULL) spriteFont = LoadImageFont(image, MAGENTA, FONT_FIRST_CHAR);
UnloadImage(image);
}
-
+
if (spriteFont.texture.id == 0)
{
TraceLog(WARNING, "[%s] SpriteFont could not be loaded, using default font", fileName);
@@ -292,14 +297,14 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
int defaultFontSize = 10; // Default Font chars height in pixel
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
- int spacing = fontSize / defaultFontSize;
+ int spacing = fontSize/defaultFontSize;
- DrawTextEx(defaultFont, text, position, fontSize, spacing, color);
+ DrawTextEx(defaultFont, text, position, (float)fontSize, spacing, color);
}
// Draw text using SpriteFont
// NOTE: chars spacing is NOT proportional to fontSize
-void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int fontSize, int spacing, Color tint)
+void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float fontSize, int spacing, Color tint)
{
int length = strlen(text);
int textOffsetX = 0;
@@ -309,17 +314,17 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int f
Rectangle rec;
- scaleFactor = (float)fontSize/spriteFont.size;
+ scaleFactor = fontSize/spriteFont.size;
- // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly
+ // NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly
// written in C code files (codified by default as UTF-8)
-
- for(int i = 0; i < length; i++)
+
+ for (int i = 0; i < length; i++)
{
// TODO: Right now we are supposing characters that follow a continous order and start at FONT_FIRST_CHAR,
// this sytem can be improved to support any characters order and init value...
// An intermediate table could be created to link char values with predefined char position index in chars rectangle array
-
+
if ((unsigned char)text[i] == 0xc2) // UTF-8 encoding identification HACK!
{
// Support UTF-8 encoded values from [0xc2 0x80] -> [0xc2 0xbf](¿)
@@ -348,8 +353,8 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int f
if (rec.x > 0)
{
- DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].x*scaleFactor,
- position.y + textOffsetY + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].y*scaleFactor,
+ DrawTexturePro(spriteFont.texture, rec, (Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].x*scaleFactor,
+ position.y + textOffsetY + spriteFont.charOffsets[(int)text[i] - FONT_FIRST_CHAR].y*scaleFactor,
rec.width*scaleFactor, rec.height*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint);
if (spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR] == 0) textOffsetX += (rec.width*scaleFactor + spacing);
@@ -376,15 +381,15 @@ const char *SubText(const char *text, int position, int length)
{
static char buffer[MAX_SUBTEXT_LENGTH];
int textLength = strlen(text);
-
+
if (position >= textLength)
{
position = textLength - 1;
length = 0;
}
-
+
if (length >= textLength) length = textLength;
-
+
for (int c = 0 ; c < length ; c++)
{
*(buffer+c) = *(text+position);
@@ -403,7 +408,7 @@ int MeasureText(const char *text, int fontSize)
int defaultFontSize = 10; // Default Font chars height in pixel
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
- int spacing = fontSize / defaultFontSize;
+ int spacing = fontSize/defaultFontSize;
vec = MeasureTextEx(defaultFont, text, fontSize, spacing);
@@ -416,17 +421,17 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int
int len = strlen(text);
int tempLen = 0; // Used to count longer text line num chars
int lenCounter = 0;
-
+
int textWidth = 0;
int tempTextWidth = 0; // Used to count longer text line width
-
+
int textHeight = spriteFont.size;
float scaleFactor;
for (int i = 0; i < len; i++)
{
lenCounter++;
-
+
if (text[i] != '\n')
{
if (spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR] != 0) textWidth += spriteFont.charAdvanceX[(int)text[i] - FONT_FIRST_CHAR];
@@ -439,10 +444,10 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int
textWidth = 0;
textHeight += (spriteFont.size + spriteFont.size/2); // NOTE: Fixed line spacing of 1.5 lines
}
-
+
if (tempLen < lenCounter) tempLen = lenCounter;
}
-
+
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
if (fontSize <= spriteFont.size) scaleFactor = 1.0f;
@@ -491,24 +496,27 @@ void DrawFPS(int posX, int posY)
static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
{
#define COLOR_EQUAL(col1, col2) ((col1.r == col2.r)&&(col1.g == col2.g)&&(col1.b == col2.b)&&(col1.a == col2.a))
-
+
int charSpacing = 0;
int lineSpacing = 0;
int x = 0;
int y = 0;
- // We allocate a temporal arrays for chars data measures,
+ // Default number of characters expected supported
+ #define MAX_FONTCHARS 128
+
+ // We allocate a temporal arrays for chars data measures,
// once we get the actual number of chars, we copy data to a sized arrays
int tempCharValues[MAX_FONTCHARS];
Rectangle tempCharRecs[MAX_FONTCHARS];
-
+
Color *pixels = GetImageData(image);
// Parse image data to get charSpacing and lineSpacing
- for(y = 0; y < image.height; y++)
+ for (y = 0; y < image.height; y++)
{
- for(x = 0; x < image.width; x++)
+ for (x = 0; x < image.width; x++)
{
if (!COLOR_EQUAL(pixels[y*image.width + x], key)) break;
}
@@ -521,7 +529,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
int charHeight = 0;
int j = 0;
- while(!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++;
+ while (!COLOR_EQUAL(pixels[(lineSpacing + j)*image.width + charSpacing], key)) j++;
charHeight = j;
@@ -531,20 +539,20 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
int xPosToRead = charSpacing;
// Parse image data to get rectangle sizes
- while((lineSpacing + lineToRead * (charHeight + lineSpacing)) < image.height)
+ while ((lineSpacing + lineToRead*(charHeight + lineSpacing)) < image.height)
{
- while((xPosToRead < image.width) &&
+ while ((xPosToRead < image.width) &&
!COLOR_EQUAL((pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead]), key))
{
tempCharValues[index] = firstChar + index;
-
+
tempCharRecs[index].x = xPosToRead;
- tempCharRecs[index].y = lineSpacing + lineToRead * (charHeight + lineSpacing);
+ tempCharRecs[index].y = lineSpacing + lineToRead*(charHeight + lineSpacing);
tempCharRecs[index].height = charHeight;
int charWidth = 0;
- while(!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++;
+ while (!COLOR_EQUAL(pixels[(lineSpacing + (charHeight+lineSpacing)*lineToRead)*image.width + xPosToRead + charWidth], key)) charWidth++;
tempCharRecs[index].width = charWidth;
@@ -556,14 +564,14 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
lineToRead++;
xPosToRead = charSpacing;
}
-
+
free(pixels);
-
+
TraceLog(DEBUG, "SpriteFont data parsed correctly from image");
-
+
// Create spritefont with all data parsed from image
SpriteFont spriteFont = { 0 };
-
+
spriteFont.texture = LoadTextureFromImage(image); // Convert loaded image to OpenGL texture
spriteFont.numChars = index;
@@ -578,13 +586,15 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
{
spriteFont.charValues[i] = tempCharValues[i];
spriteFont.charRecs[i] = tempCharRecs[i];
-
+
// NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f };
spriteFont.charAdvanceX[i] = 0;
}
-
+
spriteFont.size = spriteFont.charRecs[0].height;
+
+ TraceLog(INFO, "Image file loaded correctly as SpriteFont");
return spriteFont;
}
@@ -623,7 +633,7 @@ static SpriteFont LoadRBMF(const char *fileName)
if (rbmfFile == NULL)
{
TraceLog(WARNING, "[%s] rBMF font file could not be opened, using default font", fileName);
-
+
spriteFont = GetDefaultFont();
}
else
@@ -634,15 +644,15 @@ static SpriteFont LoadRBMF(const char *fileName)
spriteFont.numChars = (int)rbmfHeader.numChars;
- int numPixelBits = rbmfHeader.imgWidth * rbmfHeader.imgHeight / 32;
+ int numPixelBits = rbmfHeader.imgWidth*rbmfHeader.imgHeight/32;
- rbmfFileData = (unsigned int *)malloc(numPixelBits * sizeof(unsigned int));
+ rbmfFileData = (unsigned int *)malloc(numPixelBits*sizeof(unsigned int));
- for(int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile);
+ for (int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile);
- rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars * sizeof(unsigned char));
+ rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars*sizeof(unsigned char));
- for(int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile);
+ for (int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile);
// Re-construct image from rbmfFileData
//-----------------------------------------
@@ -662,10 +672,10 @@ static SpriteFont LoadRBMF(const char *fileName)
counter++;
}
-
+
Image image = LoadImageEx(imagePixels, rbmfHeader.imgWidth, rbmfHeader.imgHeight);
ImageFormat(&image, UNCOMPRESSED_GRAY_ALPHA);
-
+
free(imagePixels);
TraceLog(DEBUG, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
@@ -677,7 +687,7 @@ static SpriteFont LoadRBMF(const char *fileName)
//TraceLog(INFO, "[%s] Starting chars set reconstruction", fileName);
// Get characters data using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
- spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int));
+ spriteFont.charValues = (int *)malloc(spriteFont.numChars*sizeof(int));
spriteFont.charRecs = (Rectangle *)malloc(spriteFont.numChars*sizeof(Rectangle));
spriteFont.charOffsets = (Vector2 *)malloc(spriteFont.numChars*sizeof(Vector2));
spriteFont.charAdvanceX = (int *)malloc(spriteFont.numChars*sizeof(int));
@@ -689,12 +699,12 @@ static SpriteFont LoadRBMF(const char *fileName)
for (int i = 0; i < spriteFont.numChars; i++)
{
spriteFont.charValues[i] = (int)rbmfHeader.firstChar + i;
-
+
spriteFont.charRecs[i].x = currentPosX;
- spriteFont.charRecs[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor);
+ spriteFont.charRecs[i].y = charsDivisor + currentLine*((int)rbmfHeader.charHeight + charsDivisor);
spriteFont.charRecs[i].width = (int)rbmfCharWidthData[i];
spriteFont.charRecs[i].height = (int)rbmfHeader.charHeight;
-
+
// NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
spriteFont.charOffsets[i] = (Vector2){ 0.0f, 0.0f };
spriteFont.charAdvanceX[i] = 0;
@@ -704,15 +714,15 @@ static SpriteFont LoadRBMF(const char *fileName)
if (testPosX > spriteFont.texture.width)
{
currentLine++;
- currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i];
+ currentPosX = 2*charsDivisor + (int)rbmfCharWidthData[i];
testPosX = currentPosX;
spriteFont.charRecs[i].x = charsDivisor;
- spriteFont.charRecs[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
+ spriteFont.charRecs[i].y = charsDivisor + currentLine*(rbmfHeader.charHeight + charsDivisor);
}
else currentPosX = testPosX;
}
-
+
spriteFont.size = spriteFont.charRecs[0].height;
TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
@@ -730,20 +740,20 @@ static SpriteFont LoadRBMF(const char *fileName)
static SpriteFont LoadBMFont(const char *fileName)
{
#define MAX_BUFFER_SIZE 256
-
+
SpriteFont font = { 0 };
font.texture.id = 0;
-
+
char buffer[MAX_BUFFER_SIZE];
char *searchPoint = NULL;
-
+
int fontSize = 0;
int texWidth, texHeight;
char texFileName[128];
int numChars = 0;
int base; // Useless data
-
+
FILE *fntFile;
fntFile = fopen(fileName, "rt");
@@ -758,42 +768,42 @@ static SpriteFont LoadBMFont(const char *fileName)
fgets(buffer, MAX_BUFFER_SIZE, fntFile);
//searchPoint = strstr(buffer, "size");
//sscanf(searchPoint, "size=%i", &fontSize);
-
+
fgets(buffer, MAX_BUFFER_SIZE, fntFile);
searchPoint = strstr(buffer, "lineHeight");
sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i", &fontSize, &base, &texWidth, &texHeight);
-
+
TraceLog(DEBUG, "[%s] Font size: %i", fileName, fontSize);
TraceLog(DEBUG, "[%s] Font texture scale: %ix%i", fileName, texWidth, texHeight);
-
+
fgets(buffer, MAX_BUFFER_SIZE, fntFile);
searchPoint = strstr(buffer, "file");
sscanf(searchPoint, "file=\"%128[^\"]\"", texFileName);
-
+
TraceLog(DEBUG, "[%s] Font texture filename: %s", fileName, texFileName);
-
+
fgets(buffer, MAX_BUFFER_SIZE, fntFile);
searchPoint = strstr(buffer, "count");
sscanf(searchPoint, "count=%i", &numChars);
-
+
TraceLog(DEBUG, "[%s] Font num chars: %i", fileName, numChars);
-
+
// Compose correct path using route of .fnt file (fileName) and texFileName
char *texPath = NULL;
char *lastSlash = NULL;
lastSlash = strrchr(fileName, '/');
-
+
// NOTE: We need some extra space to avoid memory corruption on next allocations!
texPath = malloc(strlen(fileName) - strlen(lastSlash) + strlen(texFileName) + 4);
-
+
// NOTE: strcat() and strncat() required a '\0' terminated string to work!
*texPath = '\0';
strncat(texPath, fileName, strlen(fileName) - strlen(lastSlash) + 1);
strncat(texPath, texFileName, strlen(texFileName));
TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath);
-
+
font.texture = LoadTexture(texPath);
font.size = fontSize;
font.numChars = numChars;
@@ -801,35 +811,35 @@ static SpriteFont LoadBMFont(const char *fileName)
font.charRecs = (Rectangle *)malloc(numChars*sizeof(Rectangle));
font.charOffsets = (Vector2 *)malloc(numChars*sizeof(Vector2));
font.charAdvanceX = (int *)malloc(numChars*sizeof(int));
-
+
free(texPath);
-
+
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
-
+
bool unorderedChars = false;
int firstChar = 0;
-
+
for (int i = 0; i < numChars; i++)
{
fgets(buffer, MAX_BUFFER_SIZE, fntFile);
- sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i",
+ sscanf(buffer, "char id=%i x=%i y=%i width=%i height=%i xoffset=%i yoffset=%i xadvance=%i",
&charId, &charX, &charY, &charWidth, &charHeight, &charOffsetX, &charOffsetY, &charAdvanceX);
-
+
if (i == 0) firstChar = charId;
else if (i != (charId - firstChar)) unorderedChars = true;
-
+
// Save data properly in sprite font
font.charValues[i] = charId;
font.charRecs[i] = (Rectangle){ charX, charY, charWidth, charHeight };
font.charOffsets[i] = (Vector2){ (float)charOffsetX, (float)charOffsetY };
font.charAdvanceX[i] = charAdvanceX;
}
-
+
fclose(fntFile);
-
+
if (firstChar != FONT_FIRST_CHAR) TraceLog(WARNING, "BMFont not supported: expected SPACE(32) as first character, falling back to default font");
else if (unorderedChars) TraceLog(WARNING, "BMFont not supported: unordered chars data, falling back to default font");
-
+
// NOTE: Font data could be not ordered by charId: 32,33,34,35... raylib does not support unordered BMFonts
if ((firstChar != FONT_FIRST_CHAR) || (unorderedChars) || (font.texture.id == 0))
{
@@ -843,22 +853,20 @@ static SpriteFont LoadBMFont(const char *fileName)
// Generate a sprite font from TTF file data (font size required)
// TODO: Review texture packing method and generation (use oversampling)
-static SpriteFont LoadTTF(const char *fileName, int fontSize)
+static SpriteFont LoadTTF(const char *fileName, int fontSize, int firstChar, int numChars)
{
// NOTE: Generated font uses some hardcoded values
#define FONT_TEXTURE_WIDTH 512 // Font texture width
#define FONT_TEXTURE_HEIGHT 512 // Font texture height
- #define FONT_FIRST_CHAR 32 // Font first character (32 - space)
- #define FONT_NUM_CHARS 95 // ASCII 32..126 is 95 glyphs
unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25);
unsigned char *dataBitmap = (unsigned char *)malloc(FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*sizeof(unsigned char)); // One channel bitmap returned!
- stbtt_bakedchar charData[FONT_NUM_CHARS]; // ASCII 32..126 is 95 glyphs
+ stbtt_bakedchar *charData = (stbtt_bakedchar *)malloc(sizeof(stbtt_bakedchar)*numChars);
SpriteFont font = { 0 };
-
+
FILE *ttfFile = fopen(fileName, "rb");
-
+
if (ttfFile == NULL)
{
TraceLog(WARNING, "[%s] FNT file could not be opened", fileName);
@@ -868,14 +876,14 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize)
fread(ttfBuffer, 1, 1<<25, ttfFile);
// NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image...
- stbtt_BakeFontBitmap(ttfBuffer,0, fontSize, dataBitmap, FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, FONT_FIRST_CHAR, FONT_NUM_CHARS, charData);
+ stbtt_BakeFontBitmap(ttfBuffer,0, fontSize, dataBitmap, FONT_TEXTURE_WIDTH, FONT_TEXTURE_HEIGHT, firstChar, numChars, charData);
free(ttfBuffer);
-
+
// Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA
unsigned char *dataGrayAlpha = (unsigned char *)malloc(FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT*sizeof(unsigned char)*2); // Two channels
int k = 0;
-
+
for (int i = 0; i < FONT_TEXTURE_WIDTH*FONT_TEXTURE_HEIGHT; i++)
{
dataGrayAlpha[k] = 255;
@@ -883,9 +891,9 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize)
k += 2;
}
-
+
free(dataBitmap);
-
+
// Sprite font generation from TTF extracted data
Image image;
image.width = FONT_TEXTURE_WIDTH;
@@ -898,24 +906,26 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize)
UnloadImage(image); // Unloads dataGrayAlpha
font.size = fontSize;
- font.numChars = FONT_NUM_CHARS;
+ font.numChars = numChars;
font.charValues = (int *)malloc(font.numChars*sizeof(int));
font.charRecs = (Rectangle *)malloc(font.numChars*sizeof(Rectangle));
font.charOffsets = (Vector2 *)malloc(font.numChars*sizeof(Vector2));
font.charAdvanceX = (int *)malloc(font.numChars*sizeof(int));
-
+
for (int i = 0; i < font.numChars; i++)
{
- font.charValues[i] = i + FONT_FIRST_CHAR;
+ font.charValues[i] = i + firstChar;
font.charRecs[i].x = (int)charData[i].x0;
font.charRecs[i].y = (int)charData[i].y0;
font.charRecs[i].width = (int)charData[i].x1 - (int)charData[i].x0;
font.charRecs[i].height = (int)charData[i].y1 - (int)charData[i].y0;
-
+
font.charOffsets[i] = (Vector2){ charData[i].xoff, charData[i].yoff };
font.charAdvanceX[i] = (int)charData[i].xadvance;
}
+ free(charData);
+
return font;
} \ No newline at end of file
diff --git a/src/textures.c b/src/textures.c
index f5523a3e..5de0590b 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -33,18 +33,28 @@
#include <string.h> // Required for: strcmp(), strrchr(), strncmp()
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
- // Required: rlglLoadTexture() rlDeleteTextures(),
+ // Required: rlglLoadTexture() rlDeleteTextures(),
// rlglGenerateMipmaps(), some funcs for DrawTexturePro()
#include "utils.h" // rRES data decompression utility function
// NOTE: Includes Android fopen function map
+// Support only desired texture formats, by default: JPEG, PNG, BMP, TGA
+//#define STBI_NO_JPEG // Image format .jpg and .jpeg
+//#define STBI_NO_PNG
+//#define STBI_NO_BMP
+//#define STBI_NO_TGA
+#define STBI_NO_PSD
+#define STBI_NO_GIF
+#define STBI_NO_HDR
+#define STBI_NO_PIC
+#define STBI_NO_PNM // Image format .ppm and .pgm
#define STB_IMAGE_IMPLEMENTATION
#include "external/stb_image.h" // Required for: stbi_load()
// NOTE: Used to read image data (multiple formats support)
#define STB_IMAGE_RESIZE_IMPLEMENTATION
-#include "external/stb_image_resize.h" // Required for: stbir_resize_uint8()
+#include "external/stb_image_resize.h" // Required for: stbir_resize_uint8()
// NOTE: Used for image scaling on ImageResize()
//----------------------------------------------------------------------------------
@@ -95,22 +105,29 @@ Image LoadImage(const char *fileName)
if ((strcmp(GetExtension(fileName),"png") == 0) ||
(strcmp(GetExtension(fileName),"bmp") == 0) ||
(strcmp(GetExtension(fileName),"tga") == 0) ||
- (strcmp(GetExtension(fileName),"jpg") == 0) ||
- (strcmp(GetExtension(fileName),"gif") == 0) ||
- (strcmp(GetExtension(fileName),"psd") == 0) ||
- (strcmp(GetExtension(fileName),"pic") == 0))
+ (strcmp(GetExtension(fileName),"jpg") == 0)
+#ifndef STBI_NO_GIF
+ || (strcmp(GetExtension(fileName),"gif") == 0)
+#endif
+#ifndef STBI_NO_PSD
+ || (strcmp(GetExtension(fileName),"psd") == 0)
+#endif
+#ifndef STBI_NO_PIC
+ || (strcmp(GetExtension(fileName),"pic") == 0)
+#endif
+ )
{
int imgWidth = 0;
int imgHeight = 0;
int imgBpp = 0;
-
+
// NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
image.data = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 0);
image.width = imgWidth;
image.height = imgHeight;
image.mipmaps = 1;
-
+
if (imgBpp == 1) image.format = UNCOMPRESSED_GRAYSCALE;
else if (imgBpp == 2) image.format = UNCOMPRESSED_GRAY_ALPHA;
else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8;
@@ -121,12 +138,12 @@ Image LoadImage(const char *fileName)
else if (strcmp(GetExtension(fileName),"ktx") == 0) image = LoadKTX(fileName);
else if (strcmp(GetExtension(fileName),"pvr") == 0) image = LoadPVR(fileName);
else if (strcmp(GetExtension(fileName),"astc") == 0) image = LoadASTC(fileName);
-
+
if (image.data != NULL)
- {
+ {
TraceLog(INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height);
}
- else TraceLog(WARNING, "[%s] Image could not be loaded, file not recognized", fileName);
+ else TraceLog(WARNING, "[%s] Image could not be loaded, file not recognized", fileName);
return image;
}
@@ -141,11 +158,11 @@ Image LoadImageEx(Color *pixels, int width, int height)
image.height = height;
image.mipmaps = 1;
image.format = UNCOMPRESSED_R8G8B8A8;
-
+
int k = 0;
image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char));
-
+
for (int i = 0; i < image.width*image.height*4; i += 4)
{
((unsigned char *)image.data)[i] = pixels[k].r;
@@ -180,7 +197,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET);
unsigned int size = width*height;
-
+
switch (format)
{
case UNCOMPRESSED_GRAYSCALE: image.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha)
@@ -192,16 +209,16 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp
default: TraceLog(WARNING, "Image format not suported"); break;
}
-
+
fread(image.data, size, 1, rawFile);
-
+
// TODO: Check if data have been read
-
+
image.width = width;
image.height = height;
image.mipmaps = 0;
image.format = format;
-
+
fclose(rawFile);
}
@@ -326,9 +343,9 @@ Texture2D LoadTexture(const char *fileName)
Texture2D texture;
Image image = LoadImage(fileName);
-
+
if (image.data != NULL)
- {
+ {
texture = LoadTextureFromImage(image);
UnloadImage(image);
}
@@ -350,9 +367,9 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat)
texture.height = height;
texture.mipmaps = 1;
texture.format = textureFormat;
-
+
texture.id = rlglLoadTexture(data, width, height, textureFormat, 1);
-
+
return texture;
}
@@ -380,7 +397,7 @@ Texture2D LoadTextureFromImage(Image image)
texture.height = 0;
texture.mipmaps = 0;
texture.format = 0;
-
+
texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
texture.width = image.width;
@@ -395,7 +412,7 @@ Texture2D LoadTextureFromImage(Image image)
RenderTexture2D LoadRenderTexture(int width, int height)
{
RenderTexture2D target = rlglLoadRenderTexture(width, height);
-
+
return target;
}
@@ -403,7 +420,7 @@ RenderTexture2D LoadRenderTexture(int width, int height)
void UnloadImage(Image image)
{
free(image.data);
-
+
// NOTE: It becomes anoying every time a texture is loaded
//TraceLog(INFO, "Unloaded image data");
}
@@ -414,7 +431,7 @@ void UnloadTexture(Texture2D texture)
if (texture.id != 0)
{
rlDeleteTextures(texture.id);
-
+
TraceLog(INFO, "[TEX ID %i] Unloaded texture data from VRAM (GPU)", texture.id);
}
}
@@ -429,7 +446,7 @@ void UnloadRenderTexture(RenderTexture2D target)
Color *GetImageData(Image image)
{
Color *pixels = (Color *)malloc(image.width*image.height*sizeof(Color));
-
+
int k = 0;
for (int i = 0; i < image.width*image.height; i++)
@@ -442,7 +459,7 @@ Color *GetImageData(Image image)
pixels[i].g = ((unsigned char *)image.data)[k];
pixels[i].b = ((unsigned char *)image.data)[k];
pixels[i].a = 255;
-
+
k++;
} break;
case UNCOMPRESSED_GRAY_ALPHA:
@@ -451,7 +468,7 @@ Color *GetImageData(Image image)
pixels[i].g = ((unsigned char *)image.data)[k];
pixels[i].b = ((unsigned char *)image.data)[k];
pixels[i].a = ((unsigned char *)image.data)[k + 1];
-
+
k += 2;
} break;
case UNCOMPRESSED_R5G5B5A1:
@@ -462,7 +479,7 @@ Color *GetImageData(Image image)
pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111000000) >> 6)*(255/31));
pixels[i].b = (unsigned char)((float)((pixel & 0b0000000000111110) >> 1)*(255/31));
pixels[i].a = (unsigned char)((pixel & 0b0000000000000001)*255);
-
+
k++;
} break;
case UNCOMPRESSED_R5G6B5:
@@ -473,18 +490,18 @@ Color *GetImageData(Image image)
pixels[i].g = (unsigned char)((float)((pixel & 0b0000011111100000) >> 5)*(255/63));
pixels[i].b = (unsigned char)((float)(pixel & 0b0000000000011111)*(255/31));
pixels[i].a = 255;
-
+
k++;
} break;
case UNCOMPRESSED_R4G4B4A4:
{
unsigned short pixel = ((unsigned short *)image.data)[k];
-
+
pixels[i].r = (unsigned char)((float)((pixel & 0b1111000000000000) >> 12)*(255/15));
pixels[i].g = (unsigned char)((float)((pixel & 0b0000111100000000) >> 8)*(255/15));
pixels[i].b = (unsigned char)((float)((pixel & 0b0000000011110000) >> 4)*(255/15));
pixels[i].a = (unsigned char)((float)(pixel & 0b0000000000001111)*(255/15));
-
+
k++;
} break;
case UNCOMPRESSED_R8G8B8A8:
@@ -493,7 +510,7 @@ Color *GetImageData(Image image)
pixels[i].g = ((unsigned char *)image.data)[k + 1];
pixels[i].b = ((unsigned char *)image.data)[k + 2];
pixels[i].a = ((unsigned char *)image.data)[k + 3];
-
+
k += 4;
} break;
case UNCOMPRESSED_R8G8B8:
@@ -502,11 +519,11 @@ Color *GetImageData(Image image)
pixels[i].g = (unsigned char)((unsigned char *)image.data)[k + 1];
pixels[i].b = (unsigned char)((unsigned char *)image.data)[k + 2];
pixels[i].a = 255;
-
+
k += 3;
} break;
default: TraceLog(WARNING, "Format not supported for pixel data retrieval"); break;
- }
+ }
}
return pixels;
@@ -522,7 +539,7 @@ Image GetTextureData(Texture2D texture)
if (texture.format < 8)
{
image.data = rlglReadTexturePixels(texture);
-
+
if (image.data != NULL)
{
image.width = texture.width;
@@ -548,32 +565,32 @@ void ImageFormat(Image *image, int newFormat)
{
if (image->format != newFormat)
{
- if ((image->format < 8) && (newFormat < 8))
+ if ((image->format < COMPRESSED_DXT1_RGB) && (newFormat < COMPRESSED_DXT1_RGB))
{
Color *pixels = GetImageData(*image);
-
+
free(image->data);
-
+
image->format = newFormat;
int k = 0;
-
+
switch (image->format)
{
case UNCOMPRESSED_GRAYSCALE:
{
image->data = (unsigned char *)malloc(image->width*image->height*sizeof(unsigned char));
-
+
for (int i = 0; i < image->width*image->height; i++)
{
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[i].r*0.299f + (float)pixels[i].g*0.587f + (float)pixels[i].b*0.114f);
}
-
+
} break;
case UNCOMPRESSED_GRAY_ALPHA:
{
image->data = (unsigned char *)malloc(image->width*image->height*2*sizeof(unsigned char));
-
+
for (int i = 0; i < image->width*image->height*2; i += 2)
{
((unsigned char *)image->data)[i] = (unsigned char)((float)pixels[k].r*0.299f + (float)pixels[k].g*0.587f + (float)pixels[k].b*0.114f);
@@ -585,17 +602,17 @@ void ImageFormat(Image *image, int newFormat)
case UNCOMPRESSED_R5G6B5:
{
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
-
+
unsigned char r = 0;
unsigned char g = 0;
unsigned char b = 0;
-
+
for (int i = 0; i < image->width*image->height; i++)
{
r = (unsigned char)(round((float)pixels[k].r*31/255));
g = (unsigned char)(round((float)pixels[k].g*63/255));
b = (unsigned char)(round((float)pixels[k].b*31/255));
-
+
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 5 | (unsigned short)b;
}
@@ -603,7 +620,7 @@ void ImageFormat(Image *image, int newFormat)
case UNCOMPRESSED_R8G8B8:
{
image->data = (unsigned char *)malloc(image->width*image->height*3*sizeof(unsigned char));
-
+
for (int i = 0; i < image->width*image->height*3; i += 3)
{
((unsigned char *)image->data)[i] = pixels[k].r;
@@ -615,49 +632,49 @@ void ImageFormat(Image *image, int newFormat)
case UNCOMPRESSED_R5G5B5A1:
{
#define ALPHA_THRESHOLD 50
-
+
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
-
+
unsigned char r = 0;
unsigned char g = 0;
unsigned char b = 0;
unsigned char a = 0;
-
+
for (int i = 0; i < image->width*image->height; i++)
{
r = (unsigned char)(round((float)pixels[i].r*31/255));
g = (unsigned char)(round((float)pixels[i].g*31/255));
b = (unsigned char)(round((float)pixels[i].b*31/255));
a = (pixels[i].a > ALPHA_THRESHOLD) ? 1 : 0;
-
+
((unsigned short *)image->data)[i] = (unsigned short)r << 11 | (unsigned short)g << 6 | (unsigned short)b << 1 | (unsigned short)a;
}
-
+
} break;
case UNCOMPRESSED_R4G4B4A4:
{
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
-
+
unsigned char r = 0;
unsigned char g = 0;
unsigned char b = 0;
unsigned char a = 0;
-
+
for (int i = 0; i < image->width*image->height; i++)
{
r = (unsigned char)(round((float)pixels[i].r*15/255));
g = (unsigned char)(round((float)pixels[i].g*15/255));
b = (unsigned char)(round((float)pixels[i].b*15/255));
a = (unsigned char)(round((float)pixels[i].a*15/255));
-
+
((unsigned short *)image->data)[i] = (unsigned short)r << 12 | (unsigned short)g << 8| (unsigned short)b << 4| (unsigned short)a;
}
-
+
} break;
case UNCOMPRESSED_R8G8B8A8:
{
image->data = (unsigned char *)malloc(image->width*image->height*4*sizeof(unsigned char));
-
+
for (int i = 0; i < image->width*image->height*4; i += 4)
{
((unsigned char *)image->data)[i] = pixels[k].r;
@@ -669,19 +686,48 @@ void ImageFormat(Image *image, int newFormat)
} break;
default: break;
}
-
+
free(pixels);
}
else TraceLog(WARNING, "Image data format is compressed, can not be converted");
}
}
+// Apply alpha mask to image
+// NOTE 1: Returned image is RGBA - 32bit
+// NOTE 2: alphaMask should be same size as image
+void ImageAlphaMask(Image *image, Image alphaMask)
+{
+ if (image->format >= COMPRESSED_DXT1_RGB)
+ {
+ TraceLog(WARNING, "Alpha mask can not be applied to compressed data formats");
+ return;
+ }
+ else
+ {
+ // Force mask to be Grayscale
+ Image mask = ImageCopy(alphaMask);
+ ImageFormat(&mask, UNCOMPRESSED_GRAYSCALE);
+
+ // Convert image to RGBA
+ if (image->format != UNCOMPRESSED_R8G8B8A8) ImageFormat(image, UNCOMPRESSED_R8G8B8A8);
+
+ // Apply alpha mask to alpha channel
+ for (int i = 0, k = 3; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 4)
+ {
+ ((unsigned char *)image->data)[k] = ((unsigned char *)mask.data)[i];
+ }
+
+ UnloadImage(mask);
+ }
+}
+
// Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-// NOTE: In case selected bpp do not represent an known 16bit format,
+// NOTE: In case selected bpp do not represent an known 16bit format,
// dithered data is stored in the LSB part of the unsigned short
void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
{
- if (image->format >= 8)
+ if (image->format >= COMPRESSED_DXT1_RGB)
{
TraceLog(WARNING, "Compressed data formats can not be dithered");
return;
@@ -694,14 +740,14 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
else
{
Color *pixels = GetImageData(*image);
-
+
free(image->data); // free old image data
-
+
if ((image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8))
{
TraceLog(WARNING, "Image format is already 16bpp or lower, dithering could have no effect");
}
-
+
// Define new image format, check if desired bpp match internal known format
if ((rBpp == 5) && (gBpp == 6) && (bBpp == 5) && (aBpp == 0)) image->format = UNCOMPRESSED_R5G6B5;
else if ((rBpp == 5) && (gBpp == 5) && (bBpp == 5) && (aBpp == 1)) image->format = UNCOMPRESSED_R5G5B5A1;
@@ -714,13 +760,13 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
// NOTE: We will store the dithered data as unsigned short (16bpp)
image->data = (unsigned short *)malloc(image->width*image->height*sizeof(unsigned short));
-
+
Color oldpixel = WHITE;
Color newpixel = WHITE;
-
+
int error_r, error_g, error_b;
unsigned short pixel_r, pixel_g, pixel_b, pixel_a; // Used for 16bit pixel composition
-
+
#define MIN(a,b) (((a)<(b))?(a):(b))
for (int y = 0; y < image->height; y++)
@@ -728,7 +774,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
for (int x = 0; x < image->width; x++)
{
oldpixel = pixels[y*image->width + x];
-
+
// NOTE: New pixel obtained by bits truncate, it would be better to round values (check ImageFormat())
newpixel.r = oldpixel.r>>(8 - rBpp); // R bits
newpixel.g = oldpixel.g>>(8 - gBpp); // G bits
@@ -740,7 +786,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
error_r = (int)oldpixel.r - (int)(newpixel.r<<(8 - rBpp));
error_g = (int)oldpixel.g - (int)(newpixel.g<<(8 - gBpp));
error_b = (int)oldpixel.b - (int)(newpixel.b<<(8 - bBpp));
-
+
pixels[y*image->width + x] = newpixel;
// NOTE: Some cases are out of the array and should be ignored
@@ -750,21 +796,21 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)error_g*7.0f/16), 0xff);
pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)error_b*7.0f/16), 0xff);
}
-
+
if ((x > 0) && (y < (image->height - 1)))
{
pixels[(y+1)*image->width + x-1].r = MIN((int)pixels[(y+1)*image->width + x-1].r + (int)((float)error_r*3.0f/16), 0xff);
pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)error_g*3.0f/16), 0xff);
pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)error_b*3.0f/16), 0xff);
}
-
+
if (y < (image->height - 1))
{
pixels[(y+1)*image->width + x].r = MIN((int)pixels[(y+1)*image->width + x].r + (int)((float)error_r*5.0f/16), 0xff);
pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)error_g*5.0f/16), 0xff);
pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)error_b*5.0f/16), 0xff);
}
-
+
if ((x < (image->width - 1)) && (y < (image->height - 1)))
{
pixels[(y+1)*image->width + x+1].r = MIN((int)pixels[(y+1)*image->width + x+1].r + (int)((float)error_r*1.0f/16), 0xff);
@@ -776,7 +822,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
pixel_g = (unsigned short)newpixel.g;
pixel_b = (unsigned short)newpixel.b;
pixel_a = (unsigned short)newpixel.a;
-
+
((unsigned short *)image->data)[y*image->width + x] = (pixel_r<<(gBpp + bBpp + aBpp)) | (pixel_g<<(bBpp + aBpp)) | (pixel_b<<aBpp) | pixel_a;
}
}
@@ -790,7 +836,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
void ImageToPOT(Image *image, Color fillColor)
{
Color *pixels = GetImageData(*image); // Get pixels data
-
+
// Just add the required amount of pixels at the right and bottom sides of image...
int potWidth = GetNextPOT(image->width);
int potHeight = GetNextPOT(image->height);
@@ -816,13 +862,13 @@ void ImageToPOT(Image *image, Color fillColor)
free(pixels); // Free pixels data
free(image->data); // Free old image data
-
+
int format = image->format; // Store image data format to reconvert later
-
+
// TODO: Image width and height changes... do we want to store new values or keep the old ones?
// NOTE: Issues when using image.width and image.height for sprite animations...
*image = LoadImageEx(pixelsPOT, potWidth, potHeight);
-
+
free(pixelsPOT); // Free POT pixels data
ImageFormat(image, format); // Reconvert image to previous format
@@ -833,9 +879,9 @@ void ImageToPOT(Image *image, Color fillColor)
Image ImageCopy(Image image)
{
Image newImage;
-
+
int size = image.width*image.height;
-
+
switch (image.format)
{
case UNCOMPRESSED_GRAYSCALE: newImage.data = (unsigned char *)malloc(size); break; // 8 bit per pixel (no alpha)
@@ -847,24 +893,24 @@ Image ImageCopy(Image image)
case UNCOMPRESSED_R8G8B8A8: newImage.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp
default: TraceLog(WARNING, "Image format not suported for copy"); break;
}
-
+
if (newImage.data != NULL)
{
// NOTE: Size must be provided in bytes
memcpy(newImage.data, image.data, size);
-
+
newImage.width = image.width;
newImage.height = image.height;
newImage.mipmaps = image.mipmaps;
newImage.format = image.format;
}
-
+
return newImage;
}
// Crop an image to area defined by a rectangle
// NOTE: Security checks are performed in case rectangle goes out of bounds
-void ImageCrop(Image *image, Rectangle crop)
+void ImageCrop(Image *image, Rectangle crop)
{
// Security checks to make sure cropping rectangle is inside margins
if ((crop.x + crop.width) > image->width)
@@ -872,13 +918,13 @@ void ImageCrop(Image *image, Rectangle crop)
crop.width = image->width - crop.x;
TraceLog(WARNING, "Crop rectangle width out of bounds, rescaled crop width: %i", crop.width);
}
-
+
if ((crop.y + crop.height) > image->height)
{
crop.height = image->height - crop.y;
TraceLog(WARNING, "Crop rectangle height out of bounds, rescaled crop height: %i", crop.height);
}
-
+
if ((crop.x < image->width) && (crop.y < image->height))
{
// Start the cropping process
@@ -903,7 +949,7 @@ void ImageCrop(Image *image, Rectangle crop)
free(cropPixels);
- // Reformat 32bit RGBA image to original format
+ // Reformat 32bit RGBA image to original format
ImageFormat(image, format);
}
else
@@ -916,7 +962,7 @@ void ImageCrop(Image *image, Rectangle crop)
// NOTE: Uses stb default scaling filters (both bicubic):
// STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM
// STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL (high-quality Catmull-Rom)
-void ImageResize(Image *image, int newWidth, int newHeight)
+void ImageResize(Image *image, int newWidth, int newHeight)
{
// Get data as Color pixels array to work with it
Color *pixels = GetImageData(*image);
@@ -930,107 +976,132 @@ void ImageResize(Image *image, int newWidth, int newHeight)
UnloadImage(*image);
*image = LoadImageEx(output, newWidth, newHeight);
- ImageFormat(image, format); // Reformat 32bit RGBA image to original format
-
+ ImageFormat(image, format); // Reformat 32bit RGBA image to original format
+
free(output);
free(pixels);
}
// Resize and image to new size using Nearest-Neighbor scaling algorithm
-void ImageResizeNN(Image *image,int newWidth,int newHeight)
+void ImageResizeNN(Image *image,int newWidth,int newHeight)
{
Color *pixels = GetImageData(*image);
Color *output = (Color *)malloc(newWidth*newHeight*sizeof(Color));
-
+
// EDIT: added +1 to account for an early rounding problem
int x_ratio = (int)((image->width<<16)/newWidth) + 1;
int y_ratio = (int)((image->height<<16)/newHeight) + 1;
-
+
int x2, y2;
- for (int i = 0; i < newHeight; i++)
+ for (int i = 0; i < newHeight; i++)
{
- for (int j = 0; j < newWidth; j++)
+ for (int j = 0; j < newWidth; j++)
{
x2 = ((j*x_ratio) >> 16);
y2 = ((i*y_ratio) >> 16);
-
+
output[(i*newWidth) + j] = pixels[(y2*image->width) + x2] ;
- }
- }
+ }
+ }
int format = image->format;
UnloadImage(*image);
*image = LoadImageEx(output, newWidth, newHeight);
- ImageFormat(image, format); // Reformat 32bit RGBA image to original format
-
+ ImageFormat(image, format); // Reformat 32bit RGBA image to original format
+
free(output);
free(pixels);
}
// Draw an image (source) within an image (destination)
-void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
+// TODO: Feel this function could be simplified...
+void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
{
+ bool cropRequired = false;
+
// Security checks to avoid size and rectangle issues (out of bounds)
// Check that srcRec is inside src image
if (srcRec.x < 0) srcRec.x = 0;
if (srcRec.y < 0) srcRec.y = 0;
-
+
if ((srcRec.x + srcRec.width) > src.width)
{
srcRec.width = src.width - srcRec.x;
TraceLog(WARNING, "Source rectangle width out of bounds, rescaled width: %i", srcRec.width);
}
-
+
if ((srcRec.y + srcRec.height) > src.height)
{
srcRec.height = src.height - srcRec.y;
TraceLog(WARNING, "Source rectangle height out of bounds, rescaled height: %i", srcRec.height);
+ cropRequired = true;
}
+ Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it
+ ImageCrop(&srcCopy, srcRec); // Crop source image to desired source rectangle
+
// Check that dstRec is inside dst image
+ // TODO: Allow negative position within destination with cropping
if (dstRec.x < 0) dstRec.x = 0;
if (dstRec.y < 0) dstRec.y = 0;
+ // Scale source image in case destination rec size is different than source rec size
+ if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height))
+ {
+ ImageResize(&srcCopy, dstRec.width, dstRec.height);
+ }
+
if ((dstRec.x + dstRec.width) > dst->width)
{
dstRec.width = dst->width - dstRec.x;
TraceLog(WARNING, "Destination rectangle width out of bounds, rescaled width: %i", dstRec.width);
+ cropRequired = true;
}
-
+
if ((dstRec.y + dstRec.height) > dst->height)
{
dstRec.height = dst->height - dstRec.y;
TraceLog(WARNING, "Destination rectangle height out of bounds, rescaled height: %i", dstRec.height);
+ cropRequired = true;
}
- // Get dstination image data as Color pixels array to work with it
- Color *dstPixels = GetImageData(*dst);
-
- Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it
- ImageCrop(&srcCopy, srcRec); // Crop source image to desired source rectangle
-
- // Scale source image in case destination rec size is different than source rec size
- if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height))
+ if (cropRequired)
{
- ImageResize(&srcCopy, dstRec.width, dstRec.height);
+ // Crop destination rectangle if out of bounds
+ Rectangle crop = { 0, 0, dstRec.width, dstRec.height };
+ ImageCrop(&srcCopy, crop);
}
-
- // Get source image data as Color array
+
+ // Get image data as Color pixels array to work with it
+ Color *dstPixels = GetImageData(*dst);
Color *srcPixels = GetImageData(srcCopy);
+
+ UnloadImage(srcCopy); // Source copy not required any more...
- UnloadImage(srcCopy);
+ Color srcCol, dstCol;
// Blit pixels, copy source image into destination
+ // TODO: Probably out-of-bounds blitting could be considering here instead of so much cropping...
for (int j = dstRec.y; j < (dstRec.y + dstRec.height); j++)
{
for (int i = dstRec.x; i < (dstRec.x + dstRec.width); i++)
{
- dstPixels[j*dst->width + i] = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)];
+ // Alpha blending implementation
+ dstCol = dstPixels[j*dst->width + i];
+ srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)];
+
+ dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r;
+ dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g;
+ dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b;
+
+ dstPixels[j*dst->width + i] = dstCol;
+
+ // TODO: Support other blending options
}
}
-
+
UnloadImage(*dst); // NOTE: Only dst->data is unloaded
*dst = LoadImageEx(dstPixels, dst->width, dst->height);
@@ -1045,15 +1116,15 @@ Image ImageText(const char *text, int fontSize, Color color)
{
int defaultFontSize = 10; // Default Font chars height in pixel
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
- int spacing = fontSize / defaultFontSize;
-
+ int spacing = fontSize/defaultFontSize;
+
Image imText = ImageTextEx(GetDefaultFont(), text, fontSize, spacing, color);
-
+
return imText;
}
// Create an image from text (custom sprite font)
-Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing, Color tint)
+Image ImageTextEx(SpriteFont font, const char *text, float fontSize, int spacing, Color tint)
{
int length = strlen(text);
int posX = 0;
@@ -1062,19 +1133,20 @@ Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing,
// NOTE: GetTextureData() not available in OpenGL ES
Image imFont = GetTextureData(font.texture);
-
+
ImageFormat(&imFont, UNCOMPRESSED_R8G8B8A8); // Required for color tint
ImageColorTint(&imFont, tint); // Apply color tint to font
Color *fontPixels = GetImageData(imFont);
-
+
// Create image to store text
- Color *pixels = (Color *)malloc(sizeof(Color)*(int)imSize.x*(int)imSize.y);
-
+ // NOTE: Pixels are initialized to BLANK color (0, 0, 0, 0)
+ Color *pixels = (Color *)calloc((int)imSize.x*(int)imSize.y, sizeof(Color));
+
for (int i = 0; i < length; i++)
{
Rectangle letterRec = font.charRecs[(int)text[i] - 32];
-
+
for (int y = letterRec.y; y < (letterRec.y + letterRec.height); y++)
{
for (int x = posX; x < (posX + letterRec.width); x++)
@@ -1082,47 +1154,48 @@ Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing,
pixels[(y - letterRec.y)*(int)imSize.x + x] = fontPixels[y*font.texture.width + (x - posX + letterRec.x)];
}
}
-
+
posX += letterRec.width + spacing;
}
-
+
UnloadImage(imFont);
-
+
Image imText = LoadImageEx(pixels, (int)imSize.x, (int)imSize.y);
-
+
// Scale image depending on text size
- if (fontSize > (int)imSize.y)
+ if (fontSize > imSize.y)
{
- float scaleFactor = (float)fontSize/imSize.y;
+ float scaleFactor = fontSize/imSize.y;
TraceLog(INFO, "Scalefactor: %f", scaleFactor);
-
+
// Using nearest-neighbor scaling algorithm for default font
if (font.texture.id == GetDefaultFont().texture.id) ImageResizeNN(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
else ImageResize(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
}
-
+
free(pixels);
free(fontPixels);
-
+
return imText;
}
// Draw text (default font) within an image (destination)
void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color)
{
- ImageDrawTextEx(dst, position, GetDefaultFont(), text, fontSize, 0, color);
+ // NOTE: For default font, sapcing is set to desired font size / default font size (10)
+ ImageDrawTextEx(dst, position, GetDefaultFont(), text, fontSize, fontSize/10, color);
}
// Draw text (custom sprite font) within an image (destination)
-void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, int fontSize, int spacing, Color color)
+void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, float fontSize, int spacing, Color color)
{
Image imText = ImageTextEx(font, text, fontSize, spacing, color);
-
+
Rectangle srcRec = { 0, 0, imText.width, imText.height };
Rectangle dstRec = { (int)position.x, (int)position.y, imText.width, imText.height };
-
+
ImageDraw(dst, imText, srcRec, dstRec);
-
+
UnloadImage(imText);
}
@@ -1131,7 +1204,7 @@ void ImageFlipVertical(Image *image)
{
Color *srcPixels = GetImageData(*image);
Color *dstPixels = (Color *)malloc(sizeof(Color)*image->width*image->height);
-
+
for (int y = 0; y < image->height; y++)
{
for (int x = 0; x < image->width; x++)
@@ -1139,14 +1212,14 @@ void ImageFlipVertical(Image *image)
dstPixels[y*image->width + x] = srcPixels[(image->height - 1 - y)*image->width + x];
}
}
-
+
Image processed = LoadImageEx(dstPixels, image->width, image->height);
ImageFormat(&processed, image->format);
UnloadImage(*image);
-
+
free(srcPixels);
free(dstPixels);
-
+
image->data = processed.data;
}
@@ -1155,7 +1228,7 @@ void ImageFlipHorizontal(Image *image)
{
Color *srcPixels = GetImageData(*image);
Color *dstPixels = (Color *)malloc(sizeof(Color)*image->width*image->height);
-
+
for (int y = 0; y < image->height; y++)
{
for (int x = 0; x < image->width; x++)
@@ -1163,14 +1236,14 @@ void ImageFlipHorizontal(Image *image)
dstPixels[y*image->width + x] = srcPixels[y*image->width + (image->width - 1 - x)];
}
}
-
+
Image processed = LoadImageEx(dstPixels, image->width, image->height);
ImageFormat(&processed, image->format);
UnloadImage(*image);
-
+
free(srcPixels);
free(dstPixels);
-
+
image->data = processed.data;
}
@@ -1178,12 +1251,12 @@ void ImageFlipHorizontal(Image *image)
void ImageColorTint(Image *image, Color color)
{
Color *pixels = GetImageData(*image);
-
+
float cR = (float)color.r/255;
float cG = (float)color.g/255;
float cB = (float)color.b/255;
float cA = (float)color.a/255;
-
+
for (int y = 0; y < image->height; y++)
{
for (int x = 0; x < image->width; x++)
@@ -1204,7 +1277,7 @@ void ImageColorTint(Image *image, Color color)
ImageFormat(&processed, image->format);
UnloadImage(*image);
free(pixels);
-
+
image->data = processed.data;
}
@@ -1212,7 +1285,7 @@ void ImageColorTint(Image *image, Color color)
void ImageColorInvert(Image *image)
{
Color *pixels = GetImageData(*image);
-
+
for (int y = 0; y < image->height; y++)
{
for (int x = 0; x < image->width; x++)
@@ -1222,12 +1295,12 @@ void ImageColorInvert(Image *image)
pixels[y*image->width + x].b = 255 - pixels[y*image->width + x].b;
}
}
-
+
Image processed = LoadImageEx(pixels, image->width, image->height);
ImageFormat(&processed, image->format);
UnloadImage(*image);
free(pixels);
-
+
image->data = processed.data;
}
@@ -1243,12 +1316,12 @@ void ImageColorContrast(Image *image, float contrast)
{
if (contrast < -100) contrast = -100;
if (contrast > 100) contrast = 100;
-
+
contrast = (100.0 + contrast)/100.0;
contrast *= contrast;
-
+
Color *pixels = GetImageData(*image);
-
+
for (int y = 0; y < image->height; y++)
{
for (int x = 0; x < image->width; x++)
@@ -1287,7 +1360,7 @@ void ImageColorContrast(Image *image, float contrast)
ImageFormat(&processed, image->format);
UnloadImage(*image);
free(pixels);
-
+
image->data = processed.data;
}
@@ -1297,9 +1370,9 @@ void ImageColorBrightness(Image *image, int brightness)
{
if (brightness < -255) brightness = -255;
if (brightness > 255) brightness = 255;
-
+
Color *pixels = GetImageData(*image);
-
+
for (int y = 0; y < image->height; y++)
{
for (int x = 0; x < image->width; x++)
@@ -1316,7 +1389,7 @@ void ImageColorBrightness(Image *image, int brightness)
if (cB < 0) cB = 1;
if (cB > 255) cB = 255;
-
+
pixels[y*image->width + x].r = (unsigned char)cR;
pixels[y*image->width + x].g = (unsigned char)cG;
pixels[y*image->width + x].b = (unsigned char)cB;
@@ -1327,7 +1400,7 @@ void ImageColorBrightness(Image *image, int brightness)
ImageFormat(&processed, image->format);
UnloadImage(*image);
free(pixels);
-
+
image->data = processed.data;
}
@@ -1396,7 +1469,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
{
if (sourceRec.width < 0) sourceRec.x -= sourceRec.width;
if (sourceRec.height < 0) sourceRec.y -= sourceRec.height;
-
+
rlEnableTexture(texture.id);
rlPushMatrix();
@@ -1409,19 +1482,19 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal vector pointing towards viewer
// Bottom-left corner for texture and quad
- rlTexCoord2f((float)sourceRec.x / texture.width, (float)sourceRec.y / texture.height);
+ rlTexCoord2f((float)sourceRec.x/texture.width, (float)sourceRec.y/texture.height);
rlVertex2f(0.0f, 0.0f);
// Bottom-right corner for texture and quad
- rlTexCoord2f((float)sourceRec.x / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
rlVertex2f(0.0f, destRec.height);
// Top-right corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)(sourceRec.y + sourceRec.height) / texture.height);
+ rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
rlVertex2f(destRec.width, destRec.height);
// Top-left corner for texture and quad
- rlTexCoord2f((float)(sourceRec.x + sourceRec.width) / texture.width, (float)sourceRec.y / texture.height);
+ rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height);
rlVertex2f(destRec.width, 0.0f);
rlEnd();
rlPopMatrix();
@@ -1439,13 +1512,13 @@ static Image LoadDDS(const char *fileName)
{
// Required extension:
// GL_EXT_texture_compression_s3tc
-
+
// Supported tokens (defined by extensions)
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
// GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
-
+
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
@@ -1508,7 +1581,7 @@ static Image LoadDDS(const char *fileName)
else
{
ddsHeader header;
-
+
// Get the image header
fread(&header, sizeof(ddsHeader), 1, ddsFile);
@@ -1537,9 +1610,9 @@ static Image LoadDDS(const char *fileName)
{
image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short));
fread(image.data, image.width*image.height*sizeof(unsigned short), 1, ddsFile);
-
+
unsigned char alpha = 0;
-
+
// NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1
for (int i = 0; i < image.width*image.height; i++)
{
@@ -1554,9 +1627,9 @@ static Image LoadDDS(const char *fileName)
{
image.data = (unsigned short *)malloc(image.width*image.height*sizeof(unsigned short));
fread(image.data, image.width*image.height*sizeof(unsigned short), 1, ddsFile);
-
+
unsigned char alpha = 0;
-
+
// NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4
for (int i = 0; i < image.width*image.height; i++)
{
@@ -1564,7 +1637,7 @@ static Image LoadDDS(const char *fileName)
((unsigned short *)image.data)[i] = ((unsigned short *)image.data)[i] << 4;
((unsigned short *)image.data)[i] += alpha;
}
-
+
image.format = UNCOMPRESSED_R4G4B4A4;
}
}
@@ -1574,14 +1647,14 @@ static Image LoadDDS(const char *fileName)
// NOTE: not sure if this case exists...
image.data = (unsigned char *)malloc(image.width*image.height*3*sizeof(unsigned char));
fread(image.data, image.width*image.height*3, 1, ddsFile);
-
+
image.format = UNCOMPRESSED_R8G8B8;
}
else if (header.ddspf.flags == 0x41 && header.ddspf.rgbBitCount == 32) // DDS_RGBA, no compressed
{
image.data = (unsigned char *)malloc(image.width*image.height*4*sizeof(unsigned char));
fread(image.data, image.width*image.height*4, 1, ddsFile);
-
+
unsigned char blue = 0;
// NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment)
@@ -1593,7 +1666,7 @@ static Image LoadDDS(const char *fileName)
((unsigned char *)image.data)[i] = ((unsigned char *)image.data)[i + 2];
((unsigned char *)image.data)[i + 2] = blue;
}
-
+
image.format = UNCOMPRESSED_R8G8B8A8;
}
else if (((header.ddspf.flags == 0x04) || (header.ddspf.flags == 0x05)) && (header.ddspf.fourCC > 0)) // Compressed
@@ -1603,7 +1676,7 @@ static Image LoadDDS(const char *fileName)
// Calculate data size, including all mipmaps
if (header.mipmapCount > 1) bufsize = header.pitchOrLinearSize*2;
else bufsize = header.pitchOrLinearSize;
-
+
TraceLog(DEBUG, "Pitch or linear size: %i", header.pitchOrLinearSize);
image.data = (unsigned char*)malloc(bufsize*sizeof(unsigned char));
@@ -1612,7 +1685,7 @@ static Image LoadDDS(const char *fileName)
image.mipmaps = header.mipmapCount;
- switch(header.ddspf.fourCC)
+ switch (header.ddspf.fourCC)
{
case FOURCC_DXT1:
{
@@ -1625,7 +1698,7 @@ static Image LoadDDS(const char *fileName)
}
}
}
-
+
fclose(ddsFile); // Close file pointer
}
@@ -1640,9 +1713,9 @@ static Image LoadPKM(const char *fileName)
// Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1) (OpenGL ES 2.0)
// GL_ARB_ES3_compatibility (ETC2/EAC) (OpenGL ES 3.0)
-
+
// Supported tokens (defined by extensions)
- // GL_ETC1_RGB8_OES 0x8D64
+ // GL_ETC1_RGB8_OES 0x8D64
// GL_COMPRESSED_RGB8_ETC2 0x9274
// GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
@@ -1656,7 +1729,7 @@ static Image LoadPKM(const char *fileName)
unsigned short origWidth; // Original width (big-endian)
unsigned short origHeight; // Original height (big-endian)
} pkmHeader;
-
+
// Formats list
// version 10: format: 0=ETC1_RGB, [1=ETC1_RGBA, 2=ETC1_RGB_MIP, 3=ETC1_RGBA_MIP] (not used)
// version 20: format: 0=ETC1_RGB, 1=ETC2_RGB, 2=ETC2_RGBA_OLD, 3=ETC2_RGBA, 4=ETC2_RGBA1, 5=ETC2_R, 6=ETC2_RG, 7=ETC2_SIGNED_R, 8=ETC2_SIGNED_R
@@ -1665,7 +1738,7 @@ static Image LoadPKM(const char *fileName)
// NOTE: ETC is always 4bit per pixel (64 bit for each 4x4 block of pixels)
Image image;
-
+
image.data = NULL;
image.width = 0;
image.height = 0;
@@ -1695,21 +1768,21 @@ static Image LoadPKM(const char *fileName)
header.format = ((header.format & 0x00FF) << 8) | ((header.format & 0xFF00) >> 8);
header.width = ((header.width & 0x00FF) << 8) | ((header.width & 0xFF00) >> 8);
header.height = ((header.height & 0x00FF) << 8) | ((header.height & 0xFF00) >> 8);
-
+
TraceLog(DEBUG, "PKM (ETC) image width: %i", header.width);
TraceLog(DEBUG, "PKM (ETC) image height: %i", header.height);
TraceLog(DEBUG, "PKM (ETC) image format: %i", header.format);
-
+
image.width = header.width;
image.height = header.height;
image.mipmaps = 1;
-
+
int bpp = 4;
if (header.format == 3) bpp = 8;
-
+
int size = image.width*image.height*bpp/8; // Total data size in bytes
- image.data = (unsigned char*)malloc(size * sizeof(unsigned char));
+ image.data = (unsigned char*)malloc(size*sizeof(unsigned char));
fread(image.data, 1, size, pkmFile);
@@ -1717,7 +1790,7 @@ static Image LoadPKM(const char *fileName)
else if (header.format == 1) image.format = COMPRESSED_ETC2_RGB;
else if (header.format == 3) image.format = COMPRESSED_ETC2_EAC_RGBA;
}
-
+
fclose(pkmFile); // Close file pointer
}
@@ -1730,12 +1803,12 @@ static Image LoadKTX(const char *fileName)
// Required extensions:
// GL_OES_compressed_ETC1_RGB8_texture (ETC1)
// GL_ARB_ES3_compatibility (ETC2/EAC)
-
+
// Supported tokens (defined by extensions)
// GL_ETC1_RGB8_OES 0x8D64
// GL_COMPRESSED_RGB8_ETC2 0x9274
// GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
-
+
// KTX file Header (64 bytes)
// https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
typedef struct {
@@ -1754,16 +1827,16 @@ static Image LoadKTX(const char *fileName)
unsigned int mipmapLevels; // Non-mipmapped textures = 1
unsigned int keyValueDataSize; // Used to encode any arbitrary data...
} ktxHeader;
-
+
// NOTE: Before start of every mipmap data block, we have: unsigned int dataSize
-
+
Image image;
image.width = 0;
image.height = 0;
image.mipmaps = 0;
image.format = 0;
-
+
FILE *ktxFile = fopen(fileName, "rb");
if (ktxFile == NULL)
@@ -1783,26 +1856,26 @@ static Image LoadKTX(const char *fileName)
TraceLog(WARNING, "[%s] KTX file does not seem to be a valid file", fileName);
}
else
- {
+ {
image.width = header.width;
image.height = header.height;
image.mipmaps = header.mipmapLevels;
-
+
TraceLog(DEBUG, "KTX (ETC) image width: %i", header.width);
TraceLog(DEBUG, "KTX (ETC) image height: %i", header.height);
TraceLog(DEBUG, "KTX (ETC) image format: 0x%x", header.glInternalFormat);
-
+
unsigned char unused;
-
+
if (header.keyValueDataSize > 0)
{
for (int i = 0; i < header.keyValueDataSize; i++) fread(&unused, 1, 1, ktxFile);
}
-
+
int dataSize;
fread(&dataSize, sizeof(unsigned int), 1, ktxFile);
- image.data = (unsigned char*)malloc(dataSize * sizeof(unsigned char));
+ image.data = (unsigned char*)malloc(dataSize*sizeof(unsigned char));
fread(image.data, 1, dataSize, ktxFile);
@@ -1810,10 +1883,10 @@ static Image LoadKTX(const char *fileName)
else if (header.glInternalFormat == 0x9274) image.format = COMPRESSED_ETC2_RGB;
else if (header.glInternalFormat == 0x9278) image.format = COMPRESSED_ETC2_EAC_RGBA;
}
-
+
fclose(ktxFile); // Close file pointer
}
-
+
return image;
}
@@ -1823,11 +1896,11 @@ static Image LoadPVR(const char *fileName)
{
// Required extension:
// GL_IMG_texture_compression_pvrtc
-
+
// Supported tokens (defined by extensions)
// GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
// GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
-
+
#if 0 // Not used...
// PVR file v2 Header (52 bytes)
typedef struct {
@@ -1864,7 +1937,7 @@ static Image LoadPVR(const char *fileName)
unsigned int numMipmaps;
unsigned int metaDataSize;
} pvrHeaderV3;
-
+
#if 0 // Not used...
// Metadata (usually 15 bytes)
typedef struct {
@@ -1872,7 +1945,7 @@ static Image LoadPVR(const char *fileName)
unsigned int key;
unsigned int dataSize; // Not used?
unsigned char *data; // Not used?
- } pvrMetadata;
+ } pvrMetadata;
#endif
Image image;
@@ -1895,15 +1968,15 @@ static Image LoadPVR(const char *fileName)
unsigned char pvrVersion = 0;
fread(&pvrVersion, sizeof(unsigned char), 1, pvrFile);
fseek(pvrFile, 0, SEEK_SET);
-
+
// Load different PVR data formats
if (pvrVersion == 0x50)
{
pvrHeaderV3 header;
-
+
// Get PVR image header
fread(&header, sizeof(pvrHeaderV3), 1, pvrFile);
-
+
if ((header.id[0] != 'P') || (header.id[1] != 'V') || (header.id[2] != 'R') || (header.id[3] != 3))
{
TraceLog(WARNING, "[%s] PVR file does not seem to be a valid image", fileName);
@@ -1913,7 +1986,7 @@ static Image LoadPVR(const char *fileName)
image.width = header.width;
image.height = header.height;
image.mipmaps = header.numMipmaps;
-
+
// Check data format
if (((header.channels[0] == 'l') && (header.channels[1] == 0)) && (header.channelDepth[0] == 8)) image.format = UNCOMPRESSED_GRAYSCALE;
else if (((header.channels[0] == 'l') && (header.channels[1] == 'a')) && ((header.channelDepth[0] == 8) && (header.channelDepth[1] == 8))) image.format = UNCOMPRESSED_GRAY_ALPHA;
@@ -1933,14 +2006,14 @@ static Image LoadPVR(const char *fileName)
}
else if (header.channels[0] == 2) image.format = COMPRESSED_PVRT_RGB;
else if (header.channels[0] == 3) image.format = COMPRESSED_PVRT_RGBA;
-
+
// Skip meta data header
unsigned char unused = 0;
for (int i = 0; i < header.metaDataSize; i++) fread(&unused, sizeof(unsigned char), 1, pvrFile);
-
+
// Calculate data size (depends on format)
int bpp = 0;
-
+
switch (image.format)
{
case UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
@@ -1954,7 +2027,7 @@ static Image LoadPVR(const char *fileName)
case COMPRESSED_PVRT_RGBA: bpp = 4; break;
default: break;
}
-
+
int dataSize = image.width*image.height*bpp/8; // Total data size in bytes
image.data = (unsigned char*)malloc(dataSize*sizeof(unsigned char));
@@ -1976,11 +2049,11 @@ static Image LoadASTC(const char *fileName)
// Required extensions:
// GL_KHR_texture_compression_astc_hdr
// GL_KHR_texture_compression_astc_ldr
-
+
// Supported tokens (defined by extensions)
// GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0
// GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7
-
+
// ASTC file Header (16 bytes)
typedef struct {
unsigned char id[4]; // Signature: 0x13 0xAB 0xA1 0x5C
@@ -1999,7 +2072,7 @@ static Image LoadASTC(const char *fileName)
image.height = 0;
image.mipmaps = 0;
image.format = 0;
-
+
FILE *astcFile = fopen(fileName, "rb");
if (astcFile == NULL)
@@ -2012,7 +2085,7 @@ static Image LoadASTC(const char *fileName)
// Get ASTC image header
fread(&header, sizeof(astcHeader), 1, astcFile);
-
+
if ((header.id[3] != 0x5c) || (header.id[2] != 0xa1) || (header.id[1] != 0xab) || (header.id[0] != 0x13))
{
TraceLog(WARNING, "[%s] ASTC file does not seem to be a valid image", fileName);
@@ -2022,31 +2095,31 @@ static Image LoadASTC(const char *fileName)
// NOTE: Assuming Little Endian (could it be wrong?)
image.width = 0x00000000 | ((int)header.width[2] << 16) | ((int)header.width[1] << 8) | ((int)header.width[0]);
image.height = 0x00000000 | ((int)header.height[2] << 16) | ((int)header.height[1] << 8) | ((int)header.height[0]);
-
+
// NOTE: ASTC format only contains one mipmap level
image.mipmaps = 1;
-
+
TraceLog(DEBUG, "ASTC image width: %i", image.width);
TraceLog(DEBUG, "ASTC image height: %i", image.height);
TraceLog(DEBUG, "ASTC image blocks: %ix%i", header.blockX, header.blockY);
-
+
// NOTE: Each block is always stored in 128bit so we can calculate the bpp
int bpp = 128/(header.blockX*header.blockY);
// NOTE: Currently we only support 2 blocks configurations: 4x4 and 8x8
- if ((bpp == 8) || (bpp == 2))
+ if ((bpp == 8) || (bpp == 2))
{
int dataSize = image.width*image.height*bpp/8; // Data size in bytes
-
+
image.data = (unsigned char *)malloc(dataSize*sizeof(unsigned char));
fread(image.data, dataSize, 1, astcFile);
-
+
if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA;
else if (bpp == 2) image.format = COMPRESSED_ASTC_4x4_RGBA;
}
else TraceLog(WARNING, "[%s] ASTC block size configuration not supported", fileName);
}
-
+
fclose(astcFile);
}
diff --git a/templates/android_project/AndroidManifest.xml b/templates/android_project/AndroidManifest.xml
index 6755027e..1d30ab17 100644
--- a/templates/android_project/AndroidManifest.xml
+++ b/templates/android_project/AndroidManifest.xml
@@ -5,11 +5,12 @@
* This template has been created using raylib 1.2 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
-* Copyright (c) 2014 Ramon Santamaria (Ray San - [email protected])
+* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
*
-->
+<!-- NOTE: Game package name must be unique for every app/game -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.raysan5.raylib_test"
+ package="com.raylib.game_sample"
android:versionCode="1"
android:versionName="1.0" >
diff --git a/templates/android_project/jni/Android.mk b/templates/android_project/jni/Android.mk
index 15a21695..4a0bcb42 100644
--- a/templates/android_project/jni/Android.mk
+++ b/templates/android_project/jni/Android.mk
@@ -4,7 +4,7 @@
#
# Game template makefile
#
-# Copyright (c) 2014 Ramon Santamaria (Ray San - [email protected])
+# Copyright (c) 2014-2016 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.
@@ -27,7 +27,6 @@
LOCAL_PATH := $(call my-dir)
# OpenAL module (prebuilt static library)
-# NOTE: Shared library brokes the build! Why?
#--------------------------------------------------------------------
include $(CLEAR_VARS)
@@ -41,7 +40,6 @@ LOCAL_SRC_FILES := libs/libopenal.a
LOCAL_EXPORT_C_INCLUDES := include
# Build static library
-#include $(PREBUILT_SHARED_LIBRARY)
include $(PREBUILT_STATIC_LIBRARY)
#--------------------------------------------------------------------
diff --git a/templates/android_project/jni/basic_game.c b/templates/android_project/jni/basic_game.c
index a1adb287..4e8bef31 100644
--- a/templates/android_project/jni/basic_game.c
+++ b/templates/android_project/jni/basic_game.c
@@ -43,7 +43,8 @@ void android_main(struct android_app *app)
int framesCounter = 0; // Used to count frames
- PlayMusicStream(0, "ambient.ogg");
+ Music ambient = LoadMusicStream("ambient.ogg");
+ PlayMusicStream(ambient);
SetTargetFPS(60); // Not required on Android, already locked to 60 fps
//--------------------------------------------------------------------------------------
@@ -53,7 +54,7 @@ void android_main(struct android_app *app)
{
// Update
//----------------------------------------------------------------------------------
- UpdateMusicStream(0);
+ UpdateMusicStream(ambient);
switch(currentScreen)
{
@@ -158,7 +159,8 @@ void android_main(struct android_app *app)
// TODO: Unload all loaded data (textures, fonts, audio) here!
- UnloadSound(fx); // Unload sound data
+ UnloadSound(fx); // Unload sound data
+ UnloadMusicStream(ambient); // Unload music stream data
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
diff --git a/templates/android_project/jni/include/raylib.h b/templates/android_project/jni/include/raylib.h
index 19c67712..68cddc5a 100644
--- a/templates/android_project/jni/include/raylib.h
+++ b/templates/android_project/jni/include/raylib.h
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
-* raylib 1.5.0 (www.raylib.com)
+* raylib 1.6.0 (www.raylib.com)
*
* A simple and easy-to-use library to learn videogames programming
*
@@ -81,6 +81,14 @@
typedef struct android_app; // Define android_app struct (android_native_app_glue.h)
#endif
+#if defined(_WIN32) && defined(BUILDING_DLL)
+ #define RLAPI __declspec(dllexport) // We are building raylib as a Win32 DLL
+#elif defined(_WIN32) && defined(RAYLIB_DLL)
+ #define RLAPI __declspec(dllimport) // We are using raylib as a Win32 DLL
+#else
+ #define RLAPI // We are building or using raylib as a static library (or Linux shared library)
+#endif
+
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
@@ -185,17 +193,20 @@
#define GAMEPAD_PLAYER4 3 // Not supported
// Gamepad Buttons
-// NOTE: Adjusted for a PS3 USB Controller
-#define GAMEPAD_BUTTON_A 2
-#define GAMEPAD_BUTTON_B 1
-#define GAMEPAD_BUTTON_X 3
-#define GAMEPAD_BUTTON_Y 4
-#define GAMEPAD_BUTTON_R1 7
-#define GAMEPAD_BUTTON_R2 5
-#define GAMEPAD_BUTTON_L1 6
-#define GAMEPAD_BUTTON_L2 8
-#define GAMEPAD_BUTTON_SELECT 9
-#define GAMEPAD_BUTTON_START 10
+
+// PS3 USB Controller
+#define GAMEPAD_PS3_BUTTON_A 2
+#define GAMEPAD_PS3_BUTTON_B 1
+#define GAMEPAD_PS3_BUTTON_X 3
+#define GAMEPAD_PS3_BUTTON_Y 4
+#define GAMEPAD_PS3_BUTTON_R1 7
+#define GAMEPAD_PS3_BUTTON_R2 5
+#define GAMEPAD_PS3_BUTTON_L1 6
+#define GAMEPAD_PS3_BUTTON_L2 8
+#define GAMEPAD_PS3_BUTTON_SELECT 9
+#define GAMEPAD_PS3_BUTTON_START 10
+
+// TODO: Add PS3 d-pad axis
// Xbox360 USB Controller Buttons
#define GAMEPAD_XBOX_BUTTON_A 0
@@ -233,44 +244,56 @@
#define ANDROID_VOLUME_UP 24
#define ANDROID_VOLUME_DOWN 25
+// 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 (Color){ 200, 200, 200, 255 } // Light Gray
-#define GRAY (Color){ 130, 130, 130, 255 } // Gray
-#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
-#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
-#define GOLD (Color){ 255, 203, 0, 255 } // Gold
-#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
-#define PINK (Color){ 255, 109, 194, 255 } // Pink
-#define RED (Color){ 230, 41, 55, 255 } // Red
-#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
-#define GREEN (Color){ 0, 228, 48, 255 } // Green
-#define LIME (Color){ 0, 158, 47, 255 } // Lime
-#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
-#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
-#define BLUE (Color){ 0, 121, 241, 255 } // Blue
-#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
-#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
-#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
-#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
-#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
-#define BROWN (Color){ 127, 106, 79, 255 } // Brown
-#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
-
-#define WHITE (Color){ 255, 255, 255, 255 } // White
-#define BLACK (Color){ 0, 0, 0, 255 } // Black
-#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
-#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
-#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
+#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)
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
- #if !defined(_STDBOOL_H)
- typedef enum { false, true } bool;
- #define _STDBOOL_H
+ #ifndef __APPLE__
+ #if !defined(_STDBOOL_H)
+ typedef enum { false, true } bool;
+ #define _STDBOOL_H
+ #endif
+ #else
+ #include <stdbool.h>
#endif
#endif
@@ -393,7 +416,7 @@ typedef struct Mesh {
// Shader type (generic shader)
typedef struct Shader {
unsigned int id; // Shader program id
-
+
// Vertex attributes locations (default locations)
int vertexLoc; // Vertex attribute location point (default-location = 0)
int texcoordLoc; // Texcoord attribute location point (default-location = 1)
@@ -405,7 +428,7 @@ typedef struct Shader {
// Uniform locations
int mvpLoc; // ModelView-Projection matrix uniform location point (vertex shader)
int tintColorLoc; // Diffuse color uniform location point (fragment shader)
-
+
// Texture map locations (generic for any kind of map)
int mapTexture0Loc; // Map texture uniform location point (default-texture-unit = 0)
int mapTexture1Loc; // Map texture uniform location point (default-texture-unit = 1)
@@ -419,11 +442,11 @@ typedef struct Material {
Texture2D texDiffuse; // Diffuse texture (binded to shader mapTexture0Loc)
Texture2D texNormal; // Normal texture (binded to shader mapTexture1Loc)
Texture2D texSpecular; // Specular texture (binded to shader mapTexture2Loc)
-
+
Color colDiffuse; // Diffuse color
Color colAmbient; // Ambient color
Color colSpecular; // Specular color
-
+
float glossiness; // Glossiness level (Ranges from 0 to 1000)
} Material;
@@ -439,14 +462,14 @@ typedef struct LightData {
unsigned int id; // Light unique id
bool enabled; // Light enabled
int type; // Light type: LIGHT_POINT, LIGHT_DIRECTIONAL, LIGHT_SPOT
-
+
Vector3 position; // Light position
Vector3 target; // Light target: LIGHT_DIRECTIONAL and LIGHT_SPOT (cone direction target)
float radius; // Light attenuation radius light intensity reduced with distance (world distance)
-
+
Color diffuse; // Light diffuse color
float intensity; // Light intensity level
-
+
float coneAngle; // Light cone max angle: LIGHT_SPOT
} LightData, *Light;
@@ -461,19 +484,35 @@ typedef struct Ray {
// Sound source type
typedef struct Sound {
- unsigned int source; // Sound audio source id
- unsigned int buffer; // Sound audio buffer id
+ unsigned int source; // OpenAL audio source id
+ unsigned int buffer; // OpenAL audio buffer id
} Sound;
// 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
- unsigned int dataSize; // Data size in bytes
- unsigned int sampleRate; // Samples per second to be played
- short bitsPerSample; // Sample size in bits
- short channels;
} Wave;
+// 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;
+
// Texture formats
// NOTE: Support depends on OpenGL version and platform
typedef enum {
@@ -516,18 +555,6 @@ typedef enum {
GESTURE_PINCH_OUT = 512
} Gestures;
-// Touch action (fingers or mouse)
-typedef enum { TOUCH_UP, TOUCH_DOWN, TOUCH_MOVE } TouchAction;
-
-// Gesture events
-// NOTE: MAX_TOUCH_POINTS fixed to 2
-typedef struct GestureEvent {
- int touchAction;
- int pointCount;
- int pointerId[MAX_TOUCH_POINTS];
- Vector2 position[MAX_TOUCH_POINTS];
-} GestureEvent;
-
// Camera system modes
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
@@ -557,94 +584,94 @@ extern "C" { // Prevents name mangling of functions
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_ANDROID)
-void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
+RLAPI void InitWindow(int width, int height, struct android_app *state); // Init Android Activity and OpenGL Graphics
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
+RLAPI void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
#endif
-void CloseWindow(void); // Close Window and Terminate Context
-bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
-bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
-void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
-int GetScreenWidth(void); // Get current screen width
-int GetScreenHeight(void); // Get current screen height
-
-void ShowCursor(void); // Shows cursor
-void HideCursor(void); // Hides cursor
-bool IsCursorHidden(void); // Returns true if cursor is not visible
-void EnableCursor(void); // Enables cursor
-void DisableCursor(void); // Disables cursor
-
-void ClearBackground(Color color); // Sets Background Color
-void BeginDrawing(void); // Setup drawing canvas to start drawing
-void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
-
-void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera
-void End2dMode(void); // Ends 2D mode custom camera usage
-void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup)
-void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
-void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
-void EndTextureMode(void); // Ends drawing to render texture
-
-Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
-Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position
-Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
-
-void SetTargetFPS(int fps); // Set target FPS (maximum)
-float GetFPS(void); // Returns current FPS
-float GetFrameTime(void); // Returns time in seconds for one frame
-
-Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
-int GetHexValue(Color color); // Returns hexadecimal value for a Color
-float *ColorToFloat(Color color); // Converts Color to float array and normalizes
-float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array
-float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
-
-int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
-Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
-
-void SetConfigFlags(char flags); // Setup some window configuration flags
-void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
-
-bool IsFileDropped(void); // Check if a file have been dropped into window
-char **GetDroppedFiles(int *count); // Retrieve dropped files into window
-void ClearDroppedFiles(void); // Clear dropped files paths buffer
-
-void StorageSaveValue(int position, int value); // Storage save integer value (to defined position)
-int StorageLoadValue(int position); // Storage load integer value (from defined position)
+RLAPI void CloseWindow(void); // Close Window and Terminate Context
+RLAPI bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
+RLAPI bool IsWindowMinimized(void); // Detect if window has been minimized (or lost focus)
+RLAPI void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
+RLAPI int GetScreenWidth(void); // Get current screen width
+RLAPI int GetScreenHeight(void); // Get current screen height
+
+RLAPI void ShowCursor(void); // Shows cursor
+RLAPI void HideCursor(void); // Hides cursor
+RLAPI bool IsCursorHidden(void); // Returns true if cursor is not visible
+RLAPI void EnableCursor(void); // Enables cursor
+RLAPI void DisableCursor(void); // Disables cursor
+
+RLAPI void ClearBackground(Color color); // Sets Background Color
+RLAPI void BeginDrawing(void); // Setup drawing canvas 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
+RLAPI void End2dMode(void); // Ends 2D mode custom camera usage
+RLAPI void Begin3dMode(Camera camera); // Initializes 3D mode for drawing (Camera setup)
+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
+
+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 from a 3d world space position
+RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
+
+RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
+RLAPI float GetFPS(void); // Returns current FPS
+RLAPI float GetFrameTime(void); // Returns time in seconds for one frame
+
+RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color
+RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
+RLAPI float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array
+RLAPI float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
+
+RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
+RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
+
+RLAPI void SetConfigFlags(char flags); // Setup some window configuration flags
+RLAPI void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
+
+RLAPI bool IsFileDropped(void); // Check if a file have been dropped into window
+RLAPI char **GetDroppedFiles(int *count); // Retrieve dropped files into window
+RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer
+
+RLAPI void StorageSaveValue(int position, int value); // Storage save integer value (to defined position)
+RLAPI int StorageLoadValue(int position); // Storage load integer value (from defined position)
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-bool IsKeyPressed(int key); // Detect if a key has been pressed once
-bool IsKeyDown(int key); // Detect if a key is being pressed
-bool IsKeyReleased(int key); // Detect if a key has been released once
-bool IsKeyUp(int key); // Detect if a key is NOT being pressed
-int GetKeyPressed(void); // Get latest key pressed
-void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
-
-bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
-float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
-bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
-bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
-bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
-bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
+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)
+
+RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
+RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
+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
#endif
-bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
-bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
-bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
-bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
-int GetMouseX(void); // Returns mouse position X
-int GetMouseY(void); // Returns mouse position Y
-Vector2 GetMousePosition(void); // Returns mouse position XY
-void SetMousePosition(Vector2 position); // Set mouse position XY
-int GetMouseWheelMove(void); // Returns mouse wheel movement Y
+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
-int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
-int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
-Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
+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)
#if defined(PLATFORM_ANDROID)
bool IsButtonPressed(int button); // Detect if an android physic button has been pressed
@@ -655,254 +682,264 @@ bool IsButtonReleased(int button); // Detect if an android
//------------------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: gestures)
//------------------------------------------------------------------------------------
-void SetGesturesEnabled(unsigned int gestureFlags); // Enable a set of gestures using flags
-bool IsGestureDetected(int gesture); // Check if a gesture have been detected
-void ProcessGestureEvent(GestureEvent event); // Process gesture event and translate it into gestures
-void UpdateGestures(void); // Update gestures detected (called automatically in PollInputEvents())
-
-int GetTouchPointsCount(void); // Get touch points count
-int GetGestureDetected(void); // Get latest detected gesture
-float GetGestureHoldDuration(void); // Get gesture hold time in milliseconds
-Vector2 GetGestureDragVector(void); // Get gesture drag vector
-float GetGestureDragAngle(void); // Get gesture drag angle
-Vector2 GetGesturePinchVector(void); // Get gesture pinch delta
-float GetGesturePinchAngle(void); // Get gesture pinch angle
+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)
//------------------------------------------------------------------------------------
-void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
-void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
-void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
+RLAPI void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
+RLAPI void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
+RLAPI void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
-void SetCameraPosition(Vector3 position); // Set internal camera position
-void SetCameraTarget(Vector3 target); // Set internal camera target
-void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
+RLAPI void SetCameraPosition(Vector3 position); // Set internal camera position
+RLAPI void SetCameraTarget(Vector3 target); // Set internal camera target
+RLAPI void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
-void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
-void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
-void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
+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)
-void SetCameraMoveControls(int frontKey, int backKey,
- int leftKey, int rightKey,
- int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
-void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
+RLAPI void SetCameraMoveControls(int frontKey, int backKey,
+ int leftKey, int rightKey,
+ int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
+RLAPI void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
//------------------------------------------------------------------------------------
// Basic Shapes Drawing Functions (Module: shapes)
//------------------------------------------------------------------------------------
-void DrawPixel(int posX, int posY, Color color); // Draw a pixel
-void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
-void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
-void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
-void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
-void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
-void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
-void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
-void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
-void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
-void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
-void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
-void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
-void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
-void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
-void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
-void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
-void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
-
-bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
-bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
-bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
-Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
-bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
-bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
-bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
+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 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 DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
+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 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
+
+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 LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
-Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
-Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
-Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
-Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
-Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
-Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
-Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
-RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
-void UnloadImage(Image image); // Unload image from CPU memory (RAM)
-void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
-void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
-Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
-Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
-void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
-void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
-void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-Image ImageCopy(Image image); // Create an image duplicate (useful for transformations)
-void ImageCrop(Image *image, Rectangle crop); // Crop an image to a defined rectangle
-void ImageResize(Image *image, int newWidth, int newHeight); // Resize and image (bilinear filtering)
-void ImageResizeNN(Image *image,int newWidth,int newHeight); // Resize and image (Nearest-Neighbor scaling algorithm)
-Image ImageText(const char *text, int fontSize, Color color); // Create an image from text (default font)
-Image ImageTextEx(SpriteFont font, const char *text, int fontSize, int spacing, Color tint); // Create an image from text (custom sprite font)
-void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec); // Draw a source image within a destination image
-void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color); // Draw text (default font) within an image (destination)
-void ImageDrawTextEx(Image *dst, Vector2 position, SpriteFont font, const char *text, int fontSize, int spacing, Color color); // Draw text (custom sprite font) within an image (destination)
-void ImageFlipVertical(Image *image); // Flip image vertically
-void ImageFlipHorizontal(Image *image); // Flip image horizontally
-void ImageColorTint(Image *image, Color color); // Modify image color: tint
-void ImageColorInvert(Image *image); // Modify image color: invert
-void ImageColorGrayscale(Image *image); // Modify image color: grayscale
-void ImageColorContrast(Image *image, float contrast); // Modify image color: contrast (-100 to 100)
-void ImageColorBrightness(Image *image, int brightness); // Modify image color: brightness (-255 to 255)
-void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
-void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
-
-void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
-void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
-void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
-void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
-void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
+RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
+RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
+RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
+RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
+RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
+RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
+RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
+RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
+RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
+RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
+RLAPI void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
+RLAPI void UnloadRenderTexture(RenderTexture2D target); // Unload render texture from GPU memory
+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 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 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)
+RLAPI void GenTextureMipmaps(Texture2D texture); // Generate GPU mipmaps for a texture
+RLAPI void UpdateTexture(Texture2D texture, void *pixels); // Update GPU texture with new data
+
+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 GetDefaultFont(void); // Get the default SpriteFont
-SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
-void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
+RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
+RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
+RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
-void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
-void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
- int fontSize, int spacing, Color tint);
-int MeasureText(const char *text, int fontSize); // Measure string width for default font
-Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
+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);
+RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
+RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
-void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
-const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
-const char *SubText(const char *text, int position, int length); // Get a piece of a text string
+RLAPI void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
+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)
//------------------------------------------------------------------------------------
-void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
-void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
-void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
-void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
-void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
-void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
-void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
-void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
-void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
-void DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
-void DrawRay(Ray ray, Color color); // Draw a ray line
-void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
-void DrawGizmo(Vector3 position); // Draw simple gizmo
-void DrawLight(Light light); // Draw light in 3D world
-void Draw3DLine(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
-void Draw3DCircle(Vector3 center, float radius, float rotationAngle, Vector3 rotation, Color color); // Draw a circle in 3D world space
+RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
+RLAPI void DrawCircle3D(Vector3 center, float radius, float rotationAngle, Vector3 rotation, 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
+RLAPI void DrawLight(Light light); // Draw light in 3D world
//DrawTorus(), DrawTeapot() are useless...
//------------------------------------------------------------------------------------
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
-Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
-Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
-Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
-Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
-Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
-void UnloadModel(Model model); // Unload 3d model from memory
-
-Material LoadMaterial(const char *fileName); // Load material data (from file)
-Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
-Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader)
-void UnloadMaterial(Material material); // Unload material textures from VRAM
-
-void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
-void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
-void DrawModelWires(Model model, Vector3 position, float scale, Color tint); // Draw a model wires (with texture if set)
-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
-void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
-
-void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
-void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
-
-BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
-bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
-bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
-bool CheckCollisionBoxSphere(BoundingBox box, Vector3 centerSphere, float radiusSphere); // Detect collision between box and sphere
-bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphereRadius); // Detect collision between ray and sphere
-bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius, Vector3 *collisionPoint); // Detect collision between ray and sphere with extended parameters and collision point detection
-bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
-Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap
+RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
+RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
+RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
+RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
+RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
+RLAPI void UnloadModel(Model model); // Unload 3d model from memory
+
+RLAPI Mesh GenMeshCube(float width, float height, float depth); // Generate mesh: cube
+
+RLAPI Material LoadMaterial(const char *fileName); // Load material data (from file)
+RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
+RLAPI Material LoadStandardMaterial(void); // Load standard material (uses material attributes and lighting shader)
+RLAPI void UnloadMaterial(Material material); // Unload material textures from VRAM
+
+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
+
+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 with extended parameters and collision point detection
+RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
+RLAPI Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Detect collision of player radius with cubicmap
// NOTE: Return the normal vector of the impacted surface
//------------------------------------------------------------------------------------
// Shaders System Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
-Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
-void UnloadShader(Shader shader); // Unload a custom shader from memory
+RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader and bind default locations
+RLAPI void UnloadShader(Shader shader); // Unload a custom shader from memory
-Shader GetDefaultShader(void); // Get default shader
-Shader GetStandardShader(void); // Get standard shader
-Texture2D GetDefaultTexture(void); // Get default texture
+RLAPI Shader GetDefaultShader(void); // Get default shader
+RLAPI Shader GetStandardShader(void); // Get standard shader
+RLAPI Texture2D GetDefaultTexture(void); // Get default texture
-int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
-void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
-void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
-void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
+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)
-void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
-void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
+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)
-void BeginShaderMode(Shader shader); // Begin custom shader drawing
-void EndShaderMode(void); // End custom shader drawing (use default shader)
-void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
-void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
+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)
-Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
-void DestroyLight(Light light); // Destroy a light and take it out of the list
+RLAPI Light CreateLight(int type, Vector3 position, Color diffuse); // Create a new light, initialize it and add to pool
+RLAPI void DestroyLight(Light light); // Destroy a light and take it out of the list
//------------------------------------------------------------------------------------
// VR experience Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
-void InitVrDevice(int vdDevice); // Init VR device
-void CloseVrDevice(void); // Close VR device
-void UpdateVrTracking(void); // Update VR tracking (position and orientation)
-void BeginVrDrawing(void); // Begin VR drawing configuration
-void EndVrDrawing(void); // End VR drawing process (and desktop mirror)
-bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
-void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
+RLAPI void InitVrDevice(int vdDevice); // Init VR device
+RLAPI void CloseVrDevice(void); // Close VR device
+RLAPI bool IsVrDeviceReady(void); // Detect if VR device (or simulator) is ready
+RLAPI void UpdateVrTracking(void); // Update VR tracking (position and orientation)
+RLAPI void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
-void InitAudioDevice(void); // Initialize audio device and context
-void CloseAudioDevice(void); // Close the audio device and context (and music stream)
-bool IsAudioDeviceReady(void); // True if call to InitAudioDevice() was successful and CloseAudioDevice() has not been called yet
-
-Sound LoadSound(char *fileName); // Load sound to memory
-Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
-Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
-void UnloadSound(Sound sound); // Unload sound
-void PlaySound(Sound sound); // Play a sound
-void PauseSound(Sound sound); // Pause a sound
-void StopSound(Sound sound); // Stop playing a sound
-bool IsSoundPlaying(Sound sound); // Check if a sound is currently playing
-void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
-void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
-
-int PlayMusicStream(int index, char *fileName); // Start music playing (open stream)
-void UpdateMusicStream(int index); // Updates buffers for music streaming
-void StopMusicStream(int index); // Stop music playing (close stream)
-void PauseMusicStream(int index); // Pause music playing
-void ResumeMusicStream(int index); // Resume playing paused music
-bool IsMusicPlaying(int index); // Check if music is playing
-void SetMusicVolume(int index, float volume); // Set volume for music (1.0 is max level)
-void SetMusicPitch(int index, float pitch); // Set pitch for a music (1.0 is base level)
-float GetMusicTimeLength(int index); // Get current music time length (in seconds)
-float GetMusicTimePlayed(int index); // Get current music time played (in seconds)
-int GetMusicStreamCount(void); // Get number of streams loaded
+RLAPI void InitAudioDevice(void); // Initialize audio device and context
+RLAPI void CloseAudioDevice(void); // Close the audio device and context (and music stream)
+RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
+
+RLAPI Sound LoadSound(char *fileName); // Load sound to memory
+RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
+RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
+RLAPI void UnloadSound(Sound sound); // Unload sound
+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 Music LoadMusicStream(char *fileName); // Load music stream from file
+RLAPI void UnloadMusicStream(Music music); // Unload music stream
+RLAPI void PlayMusicStream(Music music); // Start music playing (open stream)
+RLAPI void UpdateMusicStream(Music music); // Updates buffers for music streaming
+RLAPI void StopMusicStream(Music music); // Stop music playing (close stream)
+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 float GetMusicTimeLength(Music music); // Get music time length (in seconds)
+RLAPI float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
+
+RLAPI AudioStream InitAudioStream(unsigned int sampleRate,
+ unsigned int sampleSize,
+ unsigned int channels); // Init audio stream (to stream audio pcm data)
+RLAPI void UpdateAudioStream(AudioStream stream, void *data, int numSamples); // 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
}
diff --git a/templates/android_project/jni/libs/libraylib.a b/templates/android_project/jni/libs/libraylib.a
index 3ee2746d..24344d0c 100644
--- a/templates/android_project/jni/libs/libraylib.a
+++ b/templates/android_project/jni/libs/libraylib.a
Binary files differ
diff --git a/tools/README.txt b/tools/rREM/README.txt
index 58bc4f0a..58bc4f0a 100644
--- a/tools/README.txt
+++ b/tools/rREM/README.txt
diff --git a/tools/rrem.exe b/tools/rREM/rrem.exe
index 0e816e4b..0e816e4b 100644
--- a/tools/rrem.exe
+++ b/tools/rREM/rrem.exe
Binary files differ