aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvictorfisac <victorfisac@gmail.com>2017-07-15 16:05:00 +0200
committervictorfisac <victorfisac@gmail.com>2017-07-15 16:05:00 +0200
commiteb7b5e59bbaec0f556c4fde21cd0bf20819a8108 (patch)
tree37d153ffc14c5ba799169b91b2e14a32b06a710a /src
parentf9277f216372179560c560427beccdd2e5c5d094 (diff)
parent910b4b5d53d9a904070807de5e8a66edadd939e3 (diff)
downloadraylib-eb7b5e59bbaec0f556c4fde21cd0bf20819a8108.tar.gz
raylib-eb7b5e59bbaec0f556c4fde21cd0bf20819a8108.zip
Merge branch 'master' of https://github.com/raysan5/raylib
Diffstat (limited to 'src')
-rw-r--r--src/Makefile185
-rw-r--r--src/android/jni/Android.mk58
-rw-r--r--src/android/jni/Application.mk3
-rw-r--r--src/android/jni/include/AL/al.h825
-rw-r--r--src/android/jni/include/AL/alc.h285
-rw-r--r--src/android/jni/include/AL/alext.h165
-rw-r--r--src/android/jni/include/AL/efx-creative.h3
-rw-r--r--src/android/jni/include/AL/efx.h758
-rw-r--r--src/android/jni/include/AL/oalMacOSX_OALExtensions.h161
-rw-r--r--src/android/jni/include/AL/oalStaticBufferExtension.h0
-rw-r--r--src/audio.c228
-rw-r--r--src/audio.h47
-rw-r--r--src/camera.h69
-rw-r--r--src/core.c659
-rw-r--r--src/easings.h2
-rw-r--r--src/external/OculusSDK/LibOVR/Include/Extras/OVR_CAPI_Util.h196
-rw-r--r--src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h3804
-rw-r--r--src/external/OculusSDK/LibOVR/Include/Extras/OVR_StereoProjection.h70
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h2234
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h84
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h158
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h102
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Keys.h53
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h156
-rw-r--r--src/external/OculusSDK/LibOVR/Include/OVR_Version.h60
-rw-r--r--src/external/OculusSDK/LibOVR/LibOVRRT32_1.dllbin1044944 -> 0 bytes
-rw-r--r--src/external/android/native_app_glue/Android.mk10
-rw-r--r--src/external/android/native_app_glue/NOTICE13
-rw-r--r--src/external/android/native_app_glue/android_native_app_glue.c441
-rw-r--r--src/external/android/native_app_glue/android_native_app_glue.h (renamed from src/android/jni/include/android_native_app_glue.h)2
-rw-r--r--src/external/gif.h931
-rw-r--r--src/external/glfw3/lib/win32/glfw3.libbin0 -> 245676 bytes
-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.abin322424 -> 0 bytes
-rw-r--r--src/external/lua/lib/liblua53dll.abin91416 -> 0 bytes
-rw-r--r--src/external/openal_soft/include/AL/alext.h12
-rw-r--r--src/external/openal_soft/lib/android/libopenal.sobin0 -> 2183284 bytes
-rw-r--r--src/external/pthread/COPYING150
-rw-r--r--src/external/pthread/include/pthread.h1368
-rw-r--r--src/external/pthread/include/sched.h183
-rw-r--r--src/external/pthread/include/semaphore.h169
-rw-r--r--src/external/pthread/lib/libpthreadGC2.abin93480 -> 0 bytes
-rw-r--r--src/external/pthread/lib/pthreadGC2.dllbin119888 -> 0 bytes
-rw-r--r--src/external/stb_image.h579
-rw-r--r--src/external/stb_image_resize.h198
-rw-r--r--src/external/stb_image_write.h61
-rw-r--r--src/external/stb_rect_pack.h70
-rw-r--r--src/external/stb_truetype.h65
-rw-r--r--src/external/stb_vorbis.c126
-rw-r--r--src/external/stb_vorbis.h12
-rw-r--r--src/gestures.h20
-rw-r--r--src/models.c234
-rw-r--r--src/physac.h198
-rw-r--r--src/raylib.h285
-rw-r--r--src/raylib_icon (renamed from src/resources)bin107212 -> 107260 bytes
-rw-r--r--src/raymath.h365
-rw-r--r--src/rlgl.c857
-rw-r--r--src/rlgl.h187
-rw-r--r--src/rres.h4
-rw-r--r--src/shapes.c74
-rw-r--r--src/text.c218
-rw-r--r--src/textures.c468
-rw-r--r--src/utils.c70
-rw-r--r--src/utils.h20
68 files changed, 4312 insertions, 15021 deletions
diff --git a/src/Makefile b/src/Makefile
index 4c2278f5..1eac71f6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,10 +1,19 @@
#******************************************************************************
#
-# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten)
-#
-# Many Thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
+# raylib makefile
#
-# Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+# Platforms supported:
+# PLATFORM_DESKTOP: Windows (win32/Win64)
+# PLATFORM_DESKTOP: Linux
+# PLATFORM_DESKTOP: OSX (Mac)
+# PLATFORM_ANDROID: Android (ARM or ARM64)
+# PLATFORM_RPI: Raspberry Pi (Raspbian)
+# PLATFORM_WEB: HTML5 (Chrome, Firefox)
+#
+# Many thanks to Milan Nikolic (@gen2brain) for implementing Android platform pipeline.
+# Many thanks to Emanuele Petriglia for his contribution on GNU/Linux pipeline.
+#
+# Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
#
# 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
@@ -29,21 +38,28 @@
# Please read the wiki to know how to compile raylib, because there are
# different methods.
-.PHONY: all clean install unistall
+.PHONY: all clean install uninstall
# define raylib platform to compile for
# possible platforms: PLATFORM_DESKTOP PLATFORM_ANDROID PLATFORM_RPI PLATFORM_WEB
PLATFORM ?= PLATFORM_DESKTOP
+# define raylib default path, required to look for emsdk and android-toolchain
+RAYLIB_PATH ?= C:/raylib
+
# define YES if you want shared/dynamic version of library instead of static (default)
-SHARED ?= NO
+SHARED_RAYLIB ?= NO
-# define NO to use OpenAL Soft as static library (or shared by default)
-SHARED_OPENAL ?= YES
+# use OpenAL Soft as shared library (.so / .dll)
+# NOTE: If defined NO, static OpenAL Soft library should be provided
+SHARED_OPENAL ?= NO
# on PLATFORM_WEB force OpenAL Soft shared library
ifeq ($(PLATFORM),PLATFORM_WEB)
- SHARED_OPENAL ?= YES
+ SHARED_OPENAL = YES
+endif
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ SHARED_OPENAL = YES
endif
# determine if the file has root access (only for installing raylib)
@@ -69,48 +85,67 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
endif
endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # Emscripten required variables
+ EMSDK_PATH = $(RAYLIB_PATH)/emsdk
+ EMSCRIPTEN_VERSION = 1.37.9
+ CLANG_VERSION=e1.37.9_64bit
+ PYTHON_VERSION=2.7.5.3_64bit
+ NODE_VERSION=4.1.1_64bit
+ export PATH=$(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
+ EMSCRIPTEN=$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
+endif
+
ifeq ($(PLATFORM),PLATFORM_ANDROID)
- # path to Android NDK
+ # Android NDK path
+ # NOTE: Required for standalone toolchain generation
ANDROID_NDK = $(ANDROID_NDK_HOME)
+
+ # Android standalone toolchain path
+ # NOTE: This path is also used if toolchain generation
+ #ANDROID_TOOLCHAIN = $(CURDIR)/toolchain
+ ANDROID_TOOLCHAIN = $(RAYLIB_PATH)/android-toolchain
- # possible Android architectures: ARM ARM64
+ # Android architecture: ARM or ARM64
ANDROID_ARCH ?= ARM
- # define YES to use clang instead of gcc
+ # Android compiler: gcc or clang
+ # NOTE: Define YES to use clang instead of gcc
ANDROID_LLVM ?= NO
-
- # standalone Android toolchain install dir
- ANDROID_TOOLCHAIN = $(CURDIR)/toolchain
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
+ # RPI cross-compiler
CROSS_COMPILE ?= NO
endif
# define raylib graphics api depending on selected platform
-ifeq ($(PLATFORM),PLATFORM_ANDROID)
- GRAPHICS = GRAPHICS_API_OPENGL_ES2
-endif
-ifeq ($(PLATFORM),PLATFORM_RPI)
- # define raylib graphics api to use (on RPI, OpenGL ES 2.0 must be used)
- GRAPHICS = GRAPHICS_API_OPENGL_ES2
-else
- # define raylib graphics api to use (OpenGL 3.3 by default)
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ # by default use OpenGL 3.3 on desktop platforms
GRAPHICS ?= GRAPHICS_API_OPENGL_33
#GRAPHICS = GRAPHICS_API_OPENGL_11 # Uncomment to use OpenGL 1.1
#GRAPHICS = GRAPHICS_API_OPENGL_21 # Uncomment to use OpenGL 2.1
endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ # on RPI OpenGL ES 2.0 must be used
+ GRAPHICS = GRAPHICS_API_OPENGL_ES2
+endif
ifeq ($(PLATFORM),PLATFORM_WEB)
+ # on HTML5 OpenGL ES 2.0 is used, emscripten translates it to WebGL 1.0
+ GRAPHICS = GRAPHICS_API_OPENGL_ES2
+endif
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ # by default use OpenGL ES 2.0 on Android
GRAPHICS = GRAPHICS_API_OPENGL_ES2
endif
# NOTE: makefiles targets require tab indentation
-
-# define compiler: gcc for C program, define as g++ for C++
+# NOTE: define compiler: gcc for C program, define as g++ for C++
# default gcc compiler
CC = gcc
+# Android toolchain compiler
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
ifeq ($(ANDROID_LLVM),YES)
@@ -128,6 +163,7 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
endif
endif
+# RPI cross-compiler
ifeq ($(PLATFORM),PLATFORM_RPI)
ifeq ($(CROSS_COMPILE),YES)
# rpi compiler
@@ -135,13 +171,15 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
endif
endif
+# HTML5 emscripten compiler
ifeq ($(PLATFORM),PLATFORM_WEB)
- # emscripten compiler
CC = emcc
endif
+# default archiver program to pack libraries
AR = ar
+# Android archiver
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
@@ -153,15 +191,28 @@ endif
# define compiler flags:
# -O1 defines optimization level
+# -Og enable debugging
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -fgnu89-inline declaring inline functions support (GCC optimized)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
-CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline -Wno-missing-braces
+# -D_DEFAULT_SOURCE use with -std=c99
+CFLAGS = -O1 -Wall -std=c99 -D_DEFAULT_SOURCE -fgnu89-inline -Wno-missing-braces
+
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ CFLAGS += -s USE_GLFW=3 -s ASSERTIONS=1 --profiling --preload-file resources
+ # -O2 # if used, also set --memory-init-file 0
+ # --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
+ # -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
+ # -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
+ # -s USE_PTHREADS=1 # multithreading support
+endif
+
+#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
# if shared library required, make sure code is compiled as position independent
-ifeq ($(SHARED),YES)
+ifeq ($(SHARED_RAYLIB),YES)
CFLAGS += -fPIC
SHAREDFLAG = BUILDING_DLL
SHAREDLIBS = -Lexternal/glfw3/lib/win32 -Lexternal/openal_soft/lib/win32 -lglfw3 -lgdi32
@@ -180,32 +231,33 @@ endif
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
-# define any directories containing required header files
-ifeq ($(PLATFORM),PLATFORM_ANDROID)
-# STB libraries and others
- INCLUDES = -I. -Iexternal
+# external required libraries (stb and others)
+INCLUDES = -I. -Iexternal
+
# OpenAL Soft library
- INCLUDES += -Iexternal/openal_soft/include
-# Android includes
- INCLUDES += -I$(ANDROID_TOOLCHAIN)/sysroot/usr/include
- INCLUDES += -I$(ANDROID_NDK)/sources/android/native_app_glue
-else
-# STB libraries and others
- INCLUDES = -I. -Iexternal
-# GLFW3 library
+INCLUDES += -Iexternal/openal_soft/include
+
+# define any directories containing required header files
+ifeq ($(PLATFORM),PLATFORM_DESKTOP)
+ # GLFW3 library
INCLUDES += -Iexternal/glfw3/include
-# OpenAL Soft library
- INCLUDES += -Iexternal/openal_soft/include
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
-# STB libraries and others
- INCLUDES = -I. -Iexternal
-# RPi libraries
+ # RPI requried libraries
INCLUDES += -I/opt/vc/include
INCLUDES += -I/opt/vc/include/interface/vmcs_host/linux
INCLUDES += -I/opt/vc/include/interface/vcos/pthreads
-# OpenAL Soft library
- INCLUDES += -Iexternal/openal_soft/include
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ # GLFW3 library
+ INCLUDES += -Iexternal/glfw3/include
+endif
+ifeq ($(PLATFORM),PLATFORM_ANDROID)
+ # Android required libraries
+ INCLUDES += -I$(ANDROID_TOOLCHAIN)/sysroot/usr/include
+ # Include android_native_app_glue.h
+ INCLUDES += -Iexternal/android/native_app_glue
+ #INCLUDES += -I$(ANDROID_NDK)/sources/android/native_app_glue
endif
# define output directory for compiled library
@@ -220,6 +272,12 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
OUTPUT_PATH = ../release/osx
endif
endif
+ifeq ($(PLATFORM),PLATFORM_RPI)
+ OUTPUT_PATH = ../release/rpi
+endif
+ifeq ($(PLATFORM),PLATFORM_WEB)
+ OUTPUT_PATH = ../release/html5
+endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
OUTPUT_PATH = ../release/android/armeabi-v7a
@@ -228,12 +286,6 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
OUTPUT_PATH = ../release/android/arm64-v8a
endif
endif
-ifeq ($(PLATFORM),PLATFORM_WEB)
- OUTPUT_PATH = ../release/html5
-endif
-ifeq ($(PLATFORM),PLATFORM_RPI)
- OUTPUT_PATH = ../release/rpi
-endif
# define all object files required with a wildcard
# The wildcard takes all files that finish with ".c", then it replaces the
@@ -243,9 +295,10 @@ OBJS += external/stb_vorbis.o
# typing 'make' will invoke the default target entry called 'all',
# in this case, the 'default' target entry is raylib
-all: toolchain raylib
+all: raylib
-# make standalone Android toolchain
+# generate standalone Android toolchain
+# NOTE: Android toolchain could already be provided
toolchain:
ifeq ($(PLATFORM),PLATFORM_ANDROID)
ifeq ($(ANDROID_ARCH),ARM)
@@ -263,10 +316,10 @@ ifeq ($(PLATFORM),PLATFORM_WEB)
emcc -O1 $(OBJS) -o $(OUTPUT_PATH)/libraylib.bc
@echo "libraylib.bc generated (web version)!"
else
- ifeq ($(SHARED),YES)
+ ifeq ($(SHARED_RAYLIB),YES)
ifeq ($(PLATFORM_OS),LINUX)
# compile raylib to shared library version for GNU/Linux.
- # WARNING: you should type "make clean" before doing this target
+ # 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
@@ -276,12 +329,12 @@ else
endif
ifeq ($(PLATFORM),PLATFORM_ANDROID)
$(CC) -shared -o $(OUTPUT_PATH)/libraylib.so $(OBJS)
- @echo "raylib shared library (libraylib.so) generated!"
+ @echo "raylib shared library generated (libraylib.so)!"
endif
else
- # compile raylib static library.
+ # compile raylib static library.
$(AR) rcs $(OUTPUT_PATH)/libraylib.a $(OBJS)
- @echo "libraylib.a generated (static library)!"
+ @echo "raylib static library generated (libraylib.a)!"
ifeq ($(SHARED_OPENAL),NO)
@echo "expected OpenAL Soft static library linking"
else
@@ -299,11 +352,11 @@ core.o : core.c raylib.h rlgl.h utils.h raymath.h gestures.h
# compile rlgl module
rlgl.o : rlgl.c rlgl.h raymath.h
$(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(GRAPHICS)
-
+
# compile shapes module
shapes.o : shapes.c raylib.h rlgl.h
$(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) -D$(SHAREDFLAG)
@@ -319,7 +372,7 @@ models.o : models.c raylib.h rlgl.h raymath.h
# compile audio module
audio.o : audio.c raylib.h
$(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(SHAREDFLAG) -D$(SHAREDOPENALFLAG)
-
+
# compile stb_vorbis library
external/stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h
$(CC) -c -o $@ $< -O1 $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
@@ -338,7 +391,7 @@ ifeq ($(ROOT),root)
# libraries and header files. These directory (/usr/local/lib and
# /usr/local/include/) are for libraries that are installed
# manually (without a package manager).
- ifeq ($(SHARED),YES)
+ ifeq ($(SHARED_RAYLIB),YES)
cp --update $(OUTPUT_PATH)/libraylib.so /usr/local/lib/libraylib.so
else
cp --update raylib.h /usr/local/include/raylib.h
@@ -354,11 +407,11 @@ endif
# it removes raylib dev files installed on the system.
# TODO: see 'install' target.
-unistall :
+uninstall :
ifeq ($(ROOT),root)
ifeq ($(PLATFORM_OS),LINUX)
rm --force /usr/local/include/raylib.h
- ifeq ($(SHARED),YES)
+ ifeq ($(SHARED_RAYLIB),YES)
rm --force /usr/local/lib/libraylib.so
else
rm --force /usr/local/lib/libraylib.a
diff --git a/src/android/jni/Android.mk b/src/android/jni/Android.mk
deleted file mode 100644
index 687c6577..00000000
--- a/src/android/jni/Android.mk
+++ /dev/null
@@ -1,58 +0,0 @@
-#**************************************************************************************************
-#
-# raylib for Android
-#
-# Static library compilation
-#
-# 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.
-#
-# 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.
-#
-#**************************************************************************************************
-
-# Path of the current directory (i.e. the directory containing the Android.mk file itself)
-LOCAL_PATH := $(call my-dir)
-
-# raylib static library compilation
-# NOTE: It uses source placed on relative path ../../src from this file
-#-----------------------------------------------------------------------
-# Makefile that will clear many LOCAL_XXX variables for you
-include $(CLEAR_VARS)
-
-# Module name
-LOCAL_MODULE := raylib
-
-# Module source files
-LOCAL_SRC_FILES :=\
- ../../core.c \
- ../../rlgl.c \
- ../../textures.c \
- ../../text.c \
- ../../shapes.c \
- ../../models.c \
- ../../utils.c \
- ../../audio.c \
- ../../external/stb_vorbis.c \
-
-# Required includes paths (.h)
-LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/include $(LOCAL_PATH)/../..
-
-# Required flags for compilation: defines PLATFORM_ANDROID and GRAPHICS_API_OPENGL_ES2
-LOCAL_CFLAGS := -Wall -std=c99 -Wno-missing-braces -DPLATFORM_ANDROID -DGRAPHICS_API_OPENGL_ES2
-
-# Build the static library libraylib.a
-include $(BUILD_STATIC_LIBRARY)
-#--------------------------------------------------------------------
diff --git a/src/android/jni/Application.mk b/src/android/jni/Application.mk
deleted file mode 100644
index fab0d7e5..00000000
--- a/src/android/jni/Application.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-APP_ABI := $(TARGET_ARCH_ABI)
-# $(warning APP_ABI $(APP_ABI))
-# $(warning LOCAL_ARM_NEON $(LOCAL_ARM_NEON))
diff --git a/src/android/jni/include/AL/al.h b/src/android/jni/include/AL/al.h
deleted file mode 100644
index e084b3ed..00000000
--- a/src/android/jni/include/AL/al.h
+++ /dev/null
@@ -1,825 +0,0 @@
-#ifndef AL_AL_H
-#define AL_AL_H
-
-#ifdef ANDROID
-#include <android/log.h>
-#ifndef LOGI
-#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,"OpenAL",__VA_ARGS__)
-#endif
-#ifndef LOGE
-#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"OpenAL",__VA_ARGS__)
-#endif
-#endif
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if defined(AL_LIBTYPE_STATIC)
- #define AL_API
-#elif defined(_WIN32) && !defined(_XBOX)
- #if defined(AL_BUILD_LIBRARY)
- #define AL_API __declspec(dllexport)
- #else
- #define AL_API __declspec(dllimport)
- #endif
-#else
- #if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
- #define AL_API __attribute__((visibility("protected")))
- #else
- #define AL_API extern
- #endif
-#endif
-
-#if defined(_WIN32)
- #define AL_APIENTRY __cdecl
-#else
- #define AL_APIENTRY
-#endif
-
-#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
- #pragma export on
-#endif
-
-/*
- * The OPENAL, ALAPI, ALAPIENTRY, AL_INVALID, AL_ILLEGAL_ENUM, and
- * AL_ILLEGAL_COMMAND macros are deprecated, but are included for
- * applications porting code from AL 1.0
- */
-#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
-
-#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;
-
-#ifdef OPENAL_FIXED_POINT
-/* Apportable tries to define int64_t and int32_t if it thinks it is needed.
- * But this is breaking in a complex project involving both pure C and C++
- * something is triggering redefinition errors. The workaround seems to be just using stdint.h.
- */
-#include <stdint.h>
-/** Types and Macros for fixed-point math */
-#ifndef INT64_MAX
-typedef long long int64_t;
-#define INT64_MAX 9223372036854775807LL
-
-#endif
-#ifndef INT32_MAX
-typedef int int32_t;
-#define INT32_MAX 2147483647
-#endif
-
-// FIXME(apportable) make this int32_t
-typedef int64_t ALfp;
-typedef int64_t ALdfp;
-
-#define ONE (1<<OPENAL_FIXED_POINT_SHIFT)
-#define TWO (2<<OPENAL_FIXED_POINT_SHIFT)
-
-#define float2ALfp(x) ((ALfp)((x) * (1<<OPENAL_FIXED_POINT_SHIFT) + ((x)>=0 ? 0.5 : -0.5)))
-#define ALfp2float(x) ((float)(x) / (1<<OPENAL_FIXED_POINT_SHIFT))
-
-#define double2ALdfp(x) ((ALdfp)((x) * (1<<OPENAL_FIXED_POINT_SHIFT) + ((x)>=0 ? 0.5 : -0.5)))
-#define ALdfp2double(x) ((double)(x) / (1<<OPENAL_FIXED_POINT_SHIFT))
-
-#define int2ALfp(x) ((ALfp)(x) << OPENAL_FIXED_POINT_SHIFT)
-#define ALfp2int(x) ((ALint)((x) >> OPENAL_FIXED_POINT_SHIFT))
-
-#define int2ALdfp(x) ((ALdfp)(x) << OPENAL_FIXED_POINT_SHIFT)
-#define ALdfp2int(x) ((ALint)((x) >> OPENAL_FIXED_POINT_SHIFT))
-
-#define ALfpMult(x,y) ((ALfp)((((int64_t)(x))*((int64_t)(y)))>>OPENAL_FIXED_POINT_SHIFT))
-#define ALfpDiv(x,y) ((ALfp)(((int64_t)(x) << OPENAL_FIXED_POINT_SHIFT) / (y)))
-
-#define ALdfpMult(x,y) ALfpMult(x,y)
-#define ALdfpDiv(x,y) ALfpDiv(x,y)
-
-#define __isnan(x) (0)
-#define __cos(x) (float2ALfp(cos(ALfp2float(x))))
-#define __sin(x) (float2ALfp(sin(ALfp2float(x))))
-#define __log10(x) (float2ALfp(log10(ALfp2float(x))))
-#define __atan(x) (float2ALfp(atan(ALfp2float(x))))
-
-#define toALfpConst(x) ((x)*(1<<OPENAL_FIXED_POINT_SHIFT))
-
-#else
-typedef float ALfp;
-typedef double ALdfp;
-
-#define float2ALfp(x) (x)
-#define ALfp2float(x) (x)
-
-#define double2ALdfp(x) (x)
-#define ALdfp2double(x) (x)
-
-#define int2ALfp(x) ((ALfp)(x))
-#define ALfp2int(x) ((ALint)(x))
-
-#define int2ALdfp(x) ((ALdfp)(x))
-#define ALdfp2int(x) ((ALint)(x))
-
-#define ALfpMult(x,y) ((x)*(y))
-#define ALfpDiv(x,y) ((x)/(y))
-
-#define ALdfpMult(x,y) ALfpMult((x),(y))
-#define ALdfpDiv(x,y) ALfpDiv((x),(y))
-
-#define __isnan(x) (0)
-#define __cos(x) cos((x))
-#define __sin(x) sin((x))
-#define __log10(x) log10((x))
-#define __atan(x) atan((x))
-
-#define toALfpConst(x) (x)
-
-#endif
-
-/** 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
-
-/** Indicate Source has relative coordinates. */
-#define AL_SOURCE_RELATIVE 0x202
-
-
-
-/**
- * Directional source, inner cone angle, in degrees.
- * Range: [0-360]
- * Default: 360
- */
-#define AL_CONE_INNER_ANGLE 0x1001
-
-/**
- * Directional source, outer cone angle, in degrees.
- * Range: [0-360]
- * Default: 360
- */
-#define AL_CONE_OUTER_ANGLE 0x1002
-
-/**
- * Specify the pitch to be applied at source.
- * Range: [0.5-2.0]
- * Default: 1.0
- */
-#define AL_PITCH 0x1003
-
-/**
- * Specify the current 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.
- * Listener position is always in the world coordinate system.
- */
-#define AL_POSITION 0x1004
-
-/** Specify the current direction. */
-#define AL_DIRECTION 0x1005
-
-/** Specify the current velocity in three dimensional space. */
-#define AL_VELOCITY 0x1006
-
-/**
- * Indicate whether source is looping.
- * Type: ALboolean?
- * Range: [AL_TRUE, AL_FALSE]
- * Default: FALSE.
- */
-#define AL_LOOPING 0x1007
-
-/**
- * Indicate the buffer to provide sound samples.
- * Type: ALuint.
- * Range: any valid Buffer id.
- */
-#define AL_BUFFER 0x1009
-
-/**
- * Indicate the gain (volume amplification) applied.
- * Type: ALfloat.
- * Range: ]0.0- ]
- * A value of 1.0 means un-attenuated/unchanged.
- * Each division by 2 equals an attenuation of -6dB.
- * Each multiplicaton with 2 equals an amplification of +6dB.
- * A value of 0.0 is meaningless with respect to a logarithmic
- * scale; it is interpreted as zero volume - the channel
- * is effectively disabled.
- */
-#define AL_GAIN 0x100A
-
-/*
- * Indicate minimum source attenuation
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- *
- * Logarthmic
- */
-#define AL_MIN_GAIN 0x100D
-
-/**
- * Indicate maximum source attenuation
- * Type: ALfloat
- * Range: [0.0 - 1.0]
- *
- * Logarthmic
- */
-#define AL_MAX_GAIN 0x100E
-
-/**
- * Indicate listener orientation.
- *
- * at/up
- */
-#define AL_ORIENTATION 0x100F
-
-/**
- * Source state information.
- */
-#define AL_SOURCE_STATE 0x1010
-#define AL_INITIAL 0x1011
-#define AL_PLAYING 0x1012
-#define AL_PAUSED 0x1013
-#define AL_STOPPED 0x1014
-
-/**
- * Buffer Queue params
- */
-#define AL_BUFFERS_QUEUED 0x1015
-#define AL_BUFFERS_PROCESSED 0x1016
-
-/**
- * Source buffer position information
- */
-#define AL_SEC_OFFSET 0x1024
-#define AL_SAMPLE_OFFSET 0x1025
-#define AL_BYTE_OFFSET 0x1026
-
-/*
- * Source type (Static, Streaming or undetermined)
- * Source is Static if a Buffer has been attached using AL_BUFFER
- * Source is Streaming if one or more Buffers have been attached using alSourceQueueBuffers
- * Source is undetermined when it has the NULL buffer attached
- */
-#define AL_SOURCE_TYPE 0x1027
-#define AL_STATIC 0x1028
-#define AL_STREAMING 0x1029
-#define AL_UNDETERMINED 0x1030
-
-/** Sound samples: format specifier. */
-#define AL_FORMAT_MONO8 0x1100
-#define AL_FORMAT_MONO16 0x1101
-#define AL_FORMAT_STEREO8 0x1102
-#define AL_FORMAT_STEREO16 0x1103
-
-/**
- * source specific reference distance
- * Type: ALfloat
- * Range: 0.0 - +inf
- *
- * At 0.0, no distance attenuation occurs. Default is
- * 1.0.
- */
-#define AL_REFERENCE_DISTANCE 0x1020
-
-/**
- * source specific rolloff factor
- * Type: ALfloat
- * Range: 0.0 - +inf
- *
- */
-#define AL_ROLLOFF_FACTOR 0x1021
-
-/**
- * Directional source, outer cone gain.
- *
- * Default: 0.0
- * Range: [0.0 - 1.0]
- * Logarithmic
- */
-#define AL_CONE_OUTER_GAIN 0x1022
-
-/**
- * Indicate distance above which sources are not
- * attenuated using the inverse clamped distance model.
- *
- * Default: +inf
- * Type: ALfloat
- * Range: 0.0 - +inf
- */
-#define AL_MAX_DISTANCE 0x1023
-
-/**
- * Sound samples: frequency, in units of Hertz [Hz].
- * This is the number of samples per second. Half of the
- * sample frequency marks the maximum significant
- * frequency component.
- */
-#define AL_FREQUENCY 0x2001
-#define AL_BITS 0x2002
-#define AL_CHANNELS 0x2003
-#define AL_SIZE 0x2004
-
-/**
- * Buffer state.
- *
- * Not supported for public use (yet).
- */
-#define AL_UNUSED 0x2010
-#define AL_PENDING 0x2011
-#define AL_PROCESSED 0x2012
-
-
-/** Errors: No Error. */
-#define AL_NO_ERROR AL_FALSE
-
-/**
- * Invalid Name paramater passed to AL call.
- */
-#define AL_INVALID_NAME 0xA001
-
-/**
- * Invalid parameter passed to AL call.
- */
-#define AL_INVALID_ENUM 0xA002
-
-/**
- * Invalid enum parameter value.
- */
-#define AL_INVALID_VALUE 0xA003
-
-/**
- * Illegal call.
- */
-#define AL_INVALID_OPERATION 0xA004
-
-
-/**
- * No mojo.
- */
-#define AL_OUT_OF_MEMORY 0xA005
-
-
-/** Context strings: Vendor Name. */
-#define AL_VENDOR 0xB001
-#define AL_VERSION 0xB002
-#define AL_RENDERER 0xB003
-#define AL_EXTENSIONS 0xB004
-
-/** Global tweakage. */
-
-/**
- * Doppler scale. Default 1.0
- */
-#define AL_DOPPLER_FACTOR 0xC000
-
-/**
- * Tweaks speed of propagation.
- */
-#define AL_DOPPLER_VELOCITY 0xC001
-
-/**
- * Speed of Sound in units per second
- */
-#define AL_SPEED_OF_SOUND 0xC003
-
-/**
- * Distance models
- *
- * used in conjunction with DistanceModel
- *
- * implicit: NONE, which disances distance attenuation.
- */
-#define AL_DISTANCE_MODEL 0xD000
-#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
-
-/**
- * Priority
- *
- * Apportable Extension.
- * Used to prevent dynamic throttling of this source.
- *
- */
-#define AL_PRIORITY 0xE001
-#define AL_PRIORITY_SLOTS 0xE002
-/*
- * 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* data );
-
-AL_API void AL_APIENTRY alGetIntegerv( ALenum param, ALint* data );
-
-AL_API void AL_APIENTRY alGetFloatv( ALenum param, ALfloat* data );
-
-AL_API void AL_APIENTRY alGetDoublev( ALenum param, ALdouble* data );
-
-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 support.
- * Obtain the most recent error generated in the AL state machine.
- */
-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 );
-
-
-/*
- * LISTENER
- * Listener represents the location and orientation of the
- * 'user' in 3D-space.
- *
- * Properties include: -
- *
- * Gain AL_GAIN ALfloat
- * Position AL_POSITION ALfloat[3]
- * Velocity AL_VELOCITY ALfloat[3]
- * Orientation AL_ORIENTATION ALfloat[6] (Forward then Up vectors)
-*/
-
-/*
- * 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 );
-
-
-/**
- * SOURCE
- * Sources represent individual sound objects in 3D-space.
- * Sources take the PCM data provided in the specified Buffer,
- * apply Source-specific modifications, and then
- * submit them to be mixed according to spatial arrangement etc.
- *
- * Properties include: -
- *
- * Gain AL_GAIN ALfloat
- * Min Gain AL_MIN_GAIN ALfloat
- * Max Gain AL_MAX_GAIN ALfloat
- * Position AL_POSITION ALfloat[3]
- * Velocity AL_VELOCITY ALfloat[3]
- * Direction AL_DIRECTION ALfloat[3]
- * Head Relative Mode AL_SOURCE_RELATIVE ALint (AL_TRUE or AL_FALSE)
- * Reference Distance AL_REFERENCE_DISTANCE ALfloat
- * Max Distance AL_MAX_DISTANCE ALfloat
- * RollOff Factor AL_ROLLOFF_FACTOR ALfloat
- * Inner Angle AL_CONE_INNER_ANGLE ALint or ALfloat
- * Outer Angle AL_CONE_OUTER_ANGLE ALint or ALfloat
- * Cone Outer Gain AL_CONE_OUTER_GAIN ALint or ALfloat
- * Pitch AL_PITCH ALfloat
- * Looping AL_LOOPING ALint (AL_TRUE or AL_FALSE)
- * MS Offset AL_MSEC_OFFSET ALint or ALfloat
- * Byte Offset AL_BYTE_OFFSET ALint or ALfloat
- * Sample Offset AL_SAMPLE_OFFSET ALint or ALfloat
- * Attached Buffer AL_BUFFER ALint
- * State (Query only) AL_SOURCE_STATE ALint
- * Buffers Queued (Query only) AL_BUFFERS_QUEUED ALint
- * Buffers Processed (Query only) AL_BUFFERS_PROCESSED ALint
- */
-
-/* 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 sid );
-
-/*
- * Set Source parameters
- */
-AL_API void AL_APIENTRY alSourcef( ALuint sid, ALenum param, ALfloat value );
-
-AL_API void AL_APIENTRY alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
-
-AL_API void AL_APIENTRY alSourcefv( ALuint sid, ALenum param, const ALfloat* values );
-
-AL_API void AL_APIENTRY alSourcei( ALuint sid, ALenum param, ALint value );
-
-AL_API void AL_APIENTRY alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
-
-AL_API void AL_APIENTRY alSourceiv( ALuint sid, ALenum param, const ALint* values );
-
-/*
- * Get Source parameters
- */
-AL_API void AL_APIENTRY alGetSourcef( ALuint sid, ALenum param, ALfloat* value );
-
-AL_API void AL_APIENTRY alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
-
-AL_API void AL_APIENTRY alGetSourcefv( ALuint sid, ALenum param, ALfloat* values );
-
-AL_API void AL_APIENTRY alGetSourcei( ALuint sid, ALenum param, ALint* value );
-
-AL_API void AL_APIENTRY alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
-
-AL_API void AL_APIENTRY alGetSourceiv( ALuint sid, ALenum param, ALint* values );
-
-
-/*
- * Source vector based playback calls
- */
-
-/* Play, replay, or resume (if paused) a list of Sources */
-AL_API void AL_APIENTRY alSourcePlayv( ALsizei ns, const ALuint *sids );
-
-/* Stop a list of Sources */
-AL_API void AL_APIENTRY alSourceStopv( ALsizei ns, const ALuint *sids );
-
-/* Rewind a list of Sources */
-AL_API void AL_APIENTRY alSourceRewindv( ALsizei ns, const ALuint *sids );
-
-/* Pause a list of Sources */
-AL_API void AL_APIENTRY alSourcePausev( ALsizei ns, const ALuint *sids );
-
-/*
- * Source based playback calls
- */
-
-/* Play, replay, or resume a Source */
-AL_API void AL_APIENTRY alSourcePlay( ALuint sid );
-
-/* Stop a Source */
-AL_API void AL_APIENTRY alSourceStop( ALuint sid );
-
-/* Rewind a Source (set playback postiton to beginning) */
-AL_API void AL_APIENTRY alSourceRewind( ALuint sid );
-
-/* Pause a Source */
-AL_API void AL_APIENTRY alSourcePause( ALuint sid );
-
-/*
- * Source Queuing
- */
-AL_API void AL_APIENTRY alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids );
-
-AL_API void AL_APIENTRY alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids );
-
-
-/**
- * BUFFER
- * Buffer objects are storage space for sample data.
- * Buffers are referred to by Sources. One Buffer can be used
- * by multiple Sources.
- *
- * Properties include: -
- *
- * Frequency (Query only) AL_FREQUENCY ALint
- * Size (Query only) AL_SIZE ALint
- * Bits (Query only) AL_BITS ALint
- * Channels (Query only) AL_CHANNELS ALint
- */
-
-/* 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 bid );
-
-/* Specify the data to be copied into a buffer */
-AL_API void AL_APIENTRY alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
-
-/*
- * Set Buffer parameters
- */
-AL_API void AL_APIENTRY alBufferf( ALuint bid, ALenum param, ALfloat value );
-
-AL_API void AL_APIENTRY alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
-
-AL_API void AL_APIENTRY alBufferfv( ALuint bid, ALenum param, const ALfloat* values );
-
-AL_API void AL_APIENTRY alBufferi( ALuint bid, ALenum param, ALint value );
-
-AL_API void AL_APIENTRY alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
-
-AL_API void AL_APIENTRY alBufferiv( ALuint bid, ALenum param, const ALint* values );
-
-/*
- * Get Buffer parameters
- */
-AL_API void AL_APIENTRY alGetBufferf( ALuint bid, ALenum param, ALfloat* value );
-
-AL_API void AL_APIENTRY alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
-
-AL_API void AL_APIENTRY alGetBufferfv( ALuint bid, ALenum param, ALfloat* values );
-
-AL_API void AL_APIENTRY alGetBufferi( ALuint bid, ALenum param, ALint* value );
-
-AL_API void AL_APIENTRY alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
-
-AL_API void AL_APIENTRY alGetBufferiv( ALuint bid, ALenum param, ALint* values );
-
-
-/*
- * Global Parameters
- */
-AL_API void AL_APIENTRY alDopplerFactor( ALfloat value );
-
-AL_API void AL_APIENTRY alDopplerVelocity( ALfloat value );
-
-AL_API void AL_APIENTRY alSpeedOfSound( ALfloat value );
-
-AL_API void AL_APIENTRY alDistanceModel( ALenum distanceModel );
-
-/*
- * Pointer-to-function types, 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* data );
-typedef void (AL_APIENTRY *LPALGETINTEGERV)( ALenum param, ALint* data );
-typedef void (AL_APIENTRY *LPALGETFLOATV)( ALenum param, ALfloat* data );
-typedef void (AL_APIENTRY *LPALGETDOUBLEV)( ALenum param, ALdouble* data );
-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 sid );
-typedef void (AL_APIENTRY *LPALSOURCEF)( ALuint sid, ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALSOURCE3F)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
-typedef void (AL_APIENTRY *LPALSOURCEFV)( ALuint sid, ALenum param, const ALfloat* values );
-typedef void (AL_APIENTRY *LPALSOURCEI)( ALuint sid, ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALSOURCE3I)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
-typedef void (AL_APIENTRY *LPALSOURCEIV)( ALuint sid, ALenum param, const ALint* values );
-typedef void (AL_APIENTRY *LPALGETSOURCEF)( ALuint sid, ALenum param, ALfloat* value );
-typedef void (AL_APIENTRY *LPALGETSOURCE3F)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
-typedef void (AL_APIENTRY *LPALGETSOURCEFV)( ALuint sid, ALenum param, ALfloat* values );
-typedef void (AL_APIENTRY *LPALGETSOURCEI)( ALuint sid, ALenum param, ALint* value );
-typedef void (AL_APIENTRY *LPALGETSOURCE3I)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
-typedef void (AL_APIENTRY *LPALGETSOURCEIV)( ALuint sid, ALenum param, ALint* values );
-typedef void (AL_APIENTRY *LPALSOURCEPLAYV)( ALsizei ns, const ALuint *sids );
-typedef void (AL_APIENTRY *LPALSOURCESTOPV)( ALsizei ns, const ALuint *sids );
-typedef void (AL_APIENTRY *LPALSOURCEREWINDV)( ALsizei ns, const ALuint *sids );
-typedef void (AL_APIENTRY *LPALSOURCEPAUSEV)( ALsizei ns, const ALuint *sids );
-typedef void (AL_APIENTRY *LPALSOURCEPLAY)( ALuint sid );
-typedef void (AL_APIENTRY *LPALSOURCESTOP)( ALuint sid );
-typedef void (AL_APIENTRY *LPALSOURCEREWIND)( ALuint sid );
-typedef void (AL_APIENTRY *LPALSOURCEPAUSE)( ALuint sid );
-typedef void (AL_APIENTRY *LPALSOURCEQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, const ALuint *bids );
-typedef void (AL_APIENTRY *LPALSOURCEUNQUEUEBUFFERS)(ALuint sid, ALsizei numEntries, ALuint *bids );
-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 bid );
-typedef void (AL_APIENTRY *LPALBUFFERDATA)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
-typedef void (AL_APIENTRY *LPALBUFFERF)( ALuint bid, ALenum param, ALfloat value);
-typedef void (AL_APIENTRY *LPALBUFFER3F)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
-typedef void (AL_APIENTRY *LPALBUFFERFV)( ALuint bid, ALenum param, const ALfloat* values );
-typedef void (AL_APIENTRY *LPALBUFFERI)( ALuint bid, ALenum param, ALint value);
-typedef void (AL_APIENTRY *LPALBUFFER3I)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
-typedef void (AL_APIENTRY *LPALBUFFERIV)( ALuint bid, ALenum param, const ALint* values );
-typedef void (AL_APIENTRY *LPALGETBUFFERF)( ALuint bid, ALenum param, ALfloat* value );
-typedef void (AL_APIENTRY *LPALGETBUFFER3F)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
-typedef void (AL_APIENTRY *LPALGETBUFFERFV)( ALuint bid, ALenum param, ALfloat* values );
-typedef void (AL_APIENTRY *LPALGETBUFFERI)( ALuint bid, ALenum param, ALint* value );
-typedef void (AL_APIENTRY *LPALGETBUFFER3I)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
-typedef void (AL_APIENTRY *LPALGETBUFFERIV)( ALuint bid, 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(TARGET_OS_MAC) && TARGET_OS_MAC
- #pragma export off
-#endif
-
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif
-
-#endif /* AL_AL_H */
diff --git a/src/android/jni/include/AL/alc.h b/src/android/jni/include/AL/alc.h
deleted file mode 100644
index 43b2ef5f..00000000
--- a/src/android/jni/include/AL/alc.h
+++ /dev/null
@@ -1,285 +0,0 @@
-#ifndef AL_ALC_H
-#define AL_ALC_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if defined(AL_LIBTYPE_STATIC)
- #define ALC_API
-#elif defined(_WIN32) && !defined(_XBOX)
- #if defined(AL_BUILD_LIBRARY)
- #define ALC_API __declspec(dllexport)
- #else
- #define ALC_API __declspec(dllimport)
- #endif
-#else
- #if defined(AL_BUILD_LIBRARY) && defined(HAVE_GCC_VISIBILITY)
- #define ALC_API __attribute__((visibility("protected")))
- #else
- #define ALC_API extern
- #endif
-#endif
-
-#if defined(_WIN32)
- #define ALC_APIENTRY __cdecl
-#else
- #define ALC_APIENTRY
-#endif
-
-#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
- #pragma export on
-#endif
-
-/*
- * The ALCAPI, ALCAPIENTRY, and ALC_INVALID macros are deprecated, but are
- * included for applications porting code from AL 1.0
- */
-#define ALCAPI ALC_API
-#define ALCAPIENTRY ALC_APIENTRY
-#define ALC_INVALID 0
-
-
-#define ALC_VERSION_0_1 1
-
-typedef struct ALCdevice_struct ALCdevice;
-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
-
-/**
- * followed by <int> Hz
- */
-#define ALC_FREQUENCY 0x1007
-
-/**
- * followed by <int> Hz
- */
-#define ALC_REFRESH 0x1008
-
-/**
- * followed by AL_TRUE, AL_FALSE
- */
-#define ALC_SYNC 0x1009
-
-/**
- * followed by <int> Num of requested Mono (3D) Sources
- */
-#define ALC_MONO_SOURCES 0x1010
-
-/**
- * followed by <int> Num of requested Stereo Sources
- */
-#define ALC_STEREO_SOURCES 0x1011
-
-/**
- * errors
- */
-
-/**
- * No error
- */
-#define ALC_NO_ERROR ALC_FALSE
-
-/**
- * No device
- */
-#define ALC_INVALID_DEVICE 0xA001
-
-/**
- * invalid context ID
- */
-#define ALC_INVALID_CONTEXT 0xA002
-
-/**
- * bad enum
- */
-#define ALC_INVALID_ENUM 0xA003
-
-/**
- * bad value
- */
-#define ALC_INVALID_VALUE 0xA004
-
-/**
- * Out of memory.
- */
-#define ALC_OUT_OF_MEMORY 0xA005
-
-
-/**
- * The Specifier string for default device
- */
-#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
-#define ALC_DEVICE_SPECIFIER 0x1005
-#define ALC_EXTENSIONS 0x1006
-
-#define ALC_MAJOR_VERSION 0x1000
-#define ALC_MINOR_VERSION 0x1001
-
-#define ALC_ATTRIBUTES_SIZE 0x1002
-#define ALC_ALL_ATTRIBUTES 0x1003
-
-
-/**
- * Capture extension
- */
-#define ALC_CAPTURE_DEVICE_SPECIFIER 0x310
-#define ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER 0x311
-#define ALC_CAPTURE_SAMPLES 0x312
-
-
-/*
- * 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 Context 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 functions
- */
-ALC_API const ALCchar * ALC_APIENTRY alcGetString( ALCdevice *device, ALCenum param );
-
-ALC_API void ALC_APIENTRY alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data );
-
-
-/*
- * Capture functions
- */
-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 types, 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 *dest );
-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(TARGET_OS_MAC) && TARGET_OS_MAC
- #pragma export off
-#endif
-
-#if defined(ANDROID)
-/*
- * OpenAL extension for suspend/resume of audio throughout application lifecycle
- */
-ALC_API void ALC_APIENTRY alcSuspend( void );
-ALC_API void ALC_APIENTRY alcResume( void );
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* AL_ALC_H */
diff --git a/src/android/jni/include/AL/alext.h b/src/android/jni/include/AL/alext.h
deleted file mode 100644
index f3c7bcae..00000000
--- a/src/android/jni/include/AL/alext.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * OpenAL cross platform audio library
- * Copyright (C) 2008 by authors.
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- * Or go to http://www.gnu.org/copyleft/lgpl.html
- */
-
-#ifndef AL_ALEXT_H
-#define AL_ALEXT_H
-
-#include <stddef.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 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 ALC_ENUMERATE_ALL_EXT
-#define ALC_ENUMERATE_ALL_EXT 1
-#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
-#define ALC_ALL_DEVICES_SPECIFIER 0x1013
-#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
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/android/jni/include/AL/efx-creative.h b/src/android/jni/include/AL/efx-creative.h
deleted file mode 100644
index 0a04c982..00000000
--- a/src/android/jni/include/AL/efx-creative.h
+++ /dev/null
@@ -1,3 +0,0 @@
-/* The tokens that would be defined here are already defined in efx.h. This
- * empty file is here to provide compatibility with Windows-based projects
- * that would include it. */
diff --git a/src/android/jni/include/AL/efx.h b/src/android/jni/include/AL/efx.h
deleted file mode 100644
index 0ccef95d..00000000
--- a/src/android/jni/include/AL/efx.h
+++ /dev/null
@@ -1,758 +0,0 @@
-#ifndef AL_EFX_H
-#define AL_EFX_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, ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISEFFECT)(ALuint);
-typedef void (AL_APIENTRY *LPALEFFECTI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALEFFECTIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALEFFECTF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALEFFECTFV)(ALuint, ALenum, 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, ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISFILTER)(ALuint);
-typedef void (AL_APIENTRY *LPALFILTERI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALFILTERIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALFILTERF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALFILTERFV)(ALuint, ALenum, 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, ALuint*);
-typedef ALboolean (AL_APIENTRY *LPALISAUXILIARYEFFECTSLOT)(ALuint);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTI)(ALuint, ALenum, ALint);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTIV)(ALuint, ALenum, ALint*);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTF)(ALuint, ALenum, ALfloat);
-typedef void (AL_APIENTRY *LPALAUXILIARYEFFECTSLOTFV)(ALuint, ALenum, 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, 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, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alEffectf(ALuint effect, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alEffectfv(ALuint effect, ALenum param, 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, 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, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alFilterf(ALuint filter, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alFilterfv(ALuint filter, ALenum param, 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, 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, ALint *piValues);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotf(ALuint effectslot, ALenum param, ALfloat flValue);
-AL_API ALvoid AL_APIENTRY alAuxiliaryEffectSlotfv(ALuint effectslot, ALenum param, 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 LOWPASS_MIN_GAIN (0.0f)
-#define LOWPASS_MAX_GAIN (1.0f)
-#define LOWPASS_DEFAULT_GAIN (1.0f)
-
-#define LOWPASS_MIN_GAINHF (0.0f)
-#define LOWPASS_MAX_GAINHF (1.0f)
-#define LOWPASS_DEFAULT_GAINHF (1.0f)
-
-/* Highpass filter */
-#define HIGHPASS_MIN_GAIN (0.0f)
-#define HIGHPASS_MAX_GAIN (1.0f)
-#define HIGHPASS_DEFAULT_GAIN (1.0f)
-
-#define HIGHPASS_MIN_GAINLF (0.0f)
-#define HIGHPASS_MAX_GAINLF (1.0f)
-#define HIGHPASS_DEFAULT_GAINLF (1.0f)
-
-/* Bandpass filter */
-#define BANDPASS_MIN_GAIN (0.0f)
-#define BANDPASS_MAX_GAIN (1.0f)
-#define BANDPASS_DEFAULT_GAIN (1.0f)
-
-#define BANDPASS_MIN_GAINHF (0.0f)
-#define BANDPASS_MAX_GAINHF (1.0f)
-#define BANDPASS_DEFAULT_GAINHF (1.0f)
-
-#define BANDPASS_MIN_GAINLF (0.0f)
-#define BANDPASS_MAX_GAINLF (1.0f)
-#define 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/src/android/jni/include/AL/oalMacOSX_OALExtensions.h b/src/android/jni/include/AL/oalMacOSX_OALExtensions.h
deleted file mode 100644
index c3db3054..00000000
--- a/src/android/jni/include/AL/oalMacOSX_OALExtensions.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/**********************************************************************************************************************************
-*
-* OpenAL cross platform audio library
-* Copyright (c) 2004-2006, Apple Computer, Inc. All rights reserved.
-* Copyright (c) 2007-2008, Apple Inc. All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
-* conditions are met:
-*
-* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
-* disclaimer in the documentation and/or other materials provided with the distribution.
-* 3. Neither the name of Apple Inc. ("Apple") nor the names of its contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS
-* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
-* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-**********************************************************************************************************************************/
-
-#ifndef __OAL_MAC_OSX_OAL_EXTENSIONS_H__
-#define __OAL_MAC_OSX_OAL_EXTENSIONS_H__
-
-#include <OpenAL/al.h>
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ALC_EXT_MAC_OSX
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-
-// Retrieve functions via alGetProcAddress() by passing in strings: alcMacOSXMixerOutputRate or alcMacOSXGetMixerOutputRate
-
-// Setting the Mixer Output Rate effectively sets the samnple rate at which the mixer
-typedef ALvoid (*alcMacOSXRenderingQualityProcPtr) (ALint value);
-typedef ALvoid (*alMacOSXRenderChannelCountProcPtr) (ALint value);
-typedef ALvoid (*alcMacOSXMixerMaxiumumBussesProcPtr) (ALint value);
-typedef ALvoid (*alcMacOSXMixerOutputRateProcPtr) (ALdouble value);
-
-typedef ALint (*alcMacOSXGetRenderingQualityProcPtr) ();
-typedef ALint (*alMacOSXGetRenderChannelCountProcPtr) ();
-typedef ALint (*alcMacOSXGetMixerMaxiumumBussesProcPtr) ();
-typedef ALdouble (*alcMacOSXGetMixerOutputRateProcPtr) ();
-
-/* Render Quality. Used with alcMacOSXRenderingQuality() */
-
- #define ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_HIGH 'rqhi'
- #define ALC_MAC_OSX_SPATIAL_RENDERING_QUALITY_LOW 'rdlo'
-
- // High Quality Spatial Algorithm suitable only for headphone use
- #define ALC_IPHONE_SPATIAL_RENDERING_QUALITY_HEADPHONES 'hdph'
-
-/*
- Render Channels. Used with alMacOSXRenderChannelCount()
- Allows a user to force OpenAL to render to stereo, regardless of the audio hardware being used
-*/
- #define ALC_MAC_OSX_RENDER_CHANNEL_COUNT_STEREO 'rcst'
-
-/* GameKit extension */
-
- #define AL_GAMEKIT 'gksr'
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- AL_EXT_SOURCE_NOTIFICATIONS
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/*
- Source Notifications
-
- Eliminates the need for continuous polling for source state by providing a
- mechanism for the application to receive source state change notifications.
- Upon receiving a notification, the application can retrieve the actual state
- corresponding to the notification ID for which the notification was sent.
- */
-
-#define AL_QUEUE_HAS_LOOPED 0x9000
-
-/*
- Notification Proc: ALSourceNotificationProc
-
- sid - source id
- notificationID - id of state that has changed
- userData - user data provided to alSourceAddNotification()
- */
-
-typedef ALvoid (*alSourceNotificationProc)(ALuint sid, ALuint notificationID, ALvoid* userData);
-
-/*
- API: alSourceAddNotification
-
- sid - source id
- notificationID - id of state for which caller wants to be notified of a change
- notifyProc - notification proc
- userData - ptr to applications user data, will be returned in the notification proc
-
- Returns AL_NO_ERROR if request is successful.
-
- Valid IDs:
- AL_SOURCE_STATE
- AL_BUFFERS_PROCESSED
- AL_QUEUE_HAS_LOOPED - notification sent when a looping source has looped to it's start point
- */
-typedef ALenum (*alSourceAddNotificationProcPtr) (ALuint sid, ALuint notificationID, alSourceNotificationProc notifyProc, ALvoid* userData);
-
-/*
- API: alSourceRemoveStateNotification
-
- sid - source id
- notificationID - id of state for which caller wants to remove an existing notification
- notifyProc - notification proc
- userData - ptr to applications user data, will be returned in the notification proc
- */
-typedef ALvoid (*alSourceRemoveNotificationProcPtr) (ALuint sid, ALuint notificationID, alSourceNotificationProc notifyProc, ALvoid* userData);
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ALC_EXT_ASA : Apple Spatial Audio Extension
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/*
- Used with the ASA API calls: alcASAGetSource(), alcASASetSource(), alcASAGetListener(), alcASASetListener()
-*/
-
-typedef ALenum (*alcASAGetSourceProcPtr) (ALuint property, ALuint source, ALvoid *data, ALuint* dataSize);
-typedef ALenum (*alcASASetSourceProcPtr) (ALuint property, ALuint source, ALvoid *data, ALuint dataSize);
-typedef ALenum (*alcASAGetListenerProcPtr) (ALuint property, ALvoid *data, ALuint* dataSize);
-typedef ALenum (*alcASASetListenerProcPtr) (ALuint property, ALvoid *data, ALuint dataSize);
-
- /* listener properties */
- #define ALC_ASA_REVERB_ON 'rvon' // type ALuint
- #define ALC_ASA_REVERB_GLOBAL_LEVEL 'rvgl' // type ALfloat -40.0 db - 40.0 db
-
- #define ALC_ASA_REVERB_ROOM_TYPE 'rvrt' // type ALint
-
- /* reverb room type presets for the ALC_ASA_REVERB_ROOM_TYPE property */
- #define ALC_ASA_REVERB_ROOM_TYPE_SmallRoom 0
- #define ALC_ASA_REVERB_ROOM_TYPE_MediumRoom 1
- #define ALC_ASA_REVERB_ROOM_TYPE_LargeRoom 2
- #define ALC_ASA_REVERB_ROOM_TYPE_MediumHall 3
- #define ALC_ASA_REVERB_ROOM_TYPE_LargeHall 4
- #define ALC_ASA_REVERB_ROOM_TYPE_Plate 5
- #define ALC_ASA_REVERB_ROOM_TYPE_MediumChamber 6
- #define ALC_ASA_REVERB_ROOM_TYPE_LargeChamber 7
- #define ALC_ASA_REVERB_ROOM_TYPE_Cathedral 8
- #define ALC_ASA_REVERB_ROOM_TYPE_LargeRoom2 9
- #define ALC_ASA_REVERB_ROOM_TYPE_MediumHall2 10
- #define ALC_ASA_REVERB_ROOM_TYPE_MediumHall3 11
- #define ALC_ASA_REVERB_ROOM_TYPE_LargeHall2 12
-
- #define ALC_ASA_REVERB_EQ_GAIN 'rveg' // type ALfloat
- #define ALC_ASA_REVERB_EQ_BANDWITH 'rveb' // type ALfloat
- #define ALC_ASA_REVERB_EQ_FREQ 'rvef' // type ALfloat
-
- /* source properties */
- #define ALC_ASA_REVERB_SEND_LEVEL 'rvsl' // type ALfloat 0.0 (dry) - 1.0 (wet) (0-100% dry/wet mix, 0.0 default)
- #define ALC_ASA_OCCLUSION 'occl' // type ALfloat -100.0 db (most occlusion) - 0.0 db (no occlusion, 0.0 default)
- #define ALC_ASA_OBSTRUCTION 'obst' // type ALfloat -100.0 db (most obstruction) - 0.0 db (no obstruction, 0.0 default)
-
-#endif // __OAL_MAC_OSX_OAL_EXTENSIONS_H__
diff --git a/src/android/jni/include/AL/oalStaticBufferExtension.h b/src/android/jni/include/AL/oalStaticBufferExtension.h
deleted file mode 100644
index e69de29b..00000000
--- a/src/android/jni/include/AL/oalStaticBufferExtension.h
+++ /dev/null
diff --git a/src/audio.c b/src/audio.c
index 659ead0f..b81d5572 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -1,26 +1,22 @@
/**********************************************************************************************
*
-* raylib.audio
+* raylib.audio - Basic funtionality to work with audio
*
-* This module provides basic functionality to work with audio:
-* Manage audio device (init/close)
-* Load and Unload audio files (WAV, OGG, FLAC, XM, MOD)
-* Play/Stop/Pause/Resume loaded audio
-* Manage mixing channels
-* Manage raw audio context
-*
-* NOTES:
-*
-* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS)
-* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32)
+* FEATURES:
+* - Manage audio device (init/close)
+* - Load and unload audio files
+* - Format wave data (sample rate, size, channels)
+* - Play/Stop/Pause/Resume loaded audio
+* - Manage mixing channels
+* - Manage raw audio context
*
* CONFIGURATION:
*
* #define AUDIO_STANDALONE
-* If defined, the module can be used as standalone library (independently of raylib).
+* Define to use the module as standalone library (independently of raylib).
* Required types and functions are defined in the same module.
*
-* #define SUPPORT_FILEFORMAT_WAV / SUPPORT_LOAD_WAV / ENABLE_LOAD_WAV
+* #define SUPPORT_FILEFORMAT_WAV
* #define SUPPORT_FILEFORMAT_OGG
* #define SUPPORT_FILEFORMAT_XM
* #define SUPPORT_FILEFORMAT_MOD
@@ -28,7 +24,9 @@
* Selected desired fileformats to be supported for loading. Some of those formats are
* supported by default, to remove support, just comment unrequired #define in this module
*
-* #define SUPPORT_RAW_AUDIO_BUFFERS
+* LIMITATIONS:
+* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS)
+* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32)
*
* DEPENDENCIES:
* OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html)
@@ -38,17 +36,16 @@
* dr_flac - FLAC audio file loading
*
* CONTRIBUTORS:
-*
-* Many thanks to Joshua Reisenauer (github: @kd7tck) for the following additions:
-* XM audio module support (jar_xm)
-* MOD audio module support (jar_mod)
-* Mixing channels support
-* Raw audio context support
+* Joshua Reisenauer (github: @kd7tck):
+* - XM audio module support (jar_xm)
+* - MOD audio module support (jar_mod)
+* - Mixing channels support
+* - Raw audio context support
*
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -67,17 +64,22 @@
*
**********************************************************************************************/
-//#define AUDIO_STANDALONE // NOTE: To use the audio module as standalone lib, just uncomment this line
+// Default configuration flags (supported features)
+//-------------------------------------------------
+#define SUPPORT_FILEFORMAT_WAV
+#define SUPPORT_FILEFORMAT_OGG
+#define SUPPORT_FILEFORMAT_XM
+//-------------------------------------------------
#if defined(AUDIO_STANDALONE)
#include "audio.h"
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#else
#include "raylib.h"
- #include "utils.h" // Required for: fopen() Android mapping, TraceLog()
+ #include "utils.h" // Required for: fopen() Android mapping
#endif
-#ifdef __APPLE__
+#if defined(__APPLE__)
#include "OpenAL/al.h" // OpenAL basic header
#include "OpenAL/alc.h" // OpenAL context header (like OpenGL, OpenAL requires a context to work)
#else
@@ -93,18 +95,26 @@
#include <string.h> // Required for: strcmp(), strncmp()
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
-//#define STB_VORBIS_HEADER_ONLY
-#include "external/stb_vorbis.h" // OGG loading functions
+#if defined(SUPPORT_FILEFORMAT_OGG)
+ //#define STB_VORBIS_HEADER_ONLY
+ #include "external/stb_vorbis.h" // OGG loading functions
+#endif
-#define JAR_XM_IMPLEMENTATION
-#include "external/jar_xm.h" // XM loading functions
+#if defined(SUPPORT_FILEFORMAT_XM)
+ #define JAR_XM_IMPLEMENTATION
+ #include "external/jar_xm.h" // XM loading functions
+#endif
-#define JAR_MOD_IMPLEMENTATION
-#include "external/jar_mod.h" // MOD loading functions
+#if defined(SUPPORT_FILEFORMAT_MOD)
+ #define JAR_MOD_IMPLEMENTATION
+ #include "external/jar_mod.h" // MOD loading functions
+#endif
-#define DR_FLAC_IMPLEMENTATION
-#define DR_FLAC_NO_WIN32_IO
-#include "external/dr_flac.h" // FLAC loading functions
+#if defined(SUPPORT_FILEFORMAT_FLAC)
+ #define DR_FLAC_IMPLEMENTATION
+ #define DR_FLAC_NO_WIN32_IO
+ #include "external/dr_flac.h" // FLAC loading functions
+#endif
#ifdef _MSC_VER
#undef bool
@@ -139,10 +149,18 @@ typedef enum { MUSIC_AUDIO_OGG = 0, MUSIC_AUDIO_FLAC, MUSIC_MODULE_XM, MUSIC_MOD
// Music type (file streaming from memory)
typedef struct MusicData {
MusicContextType ctxType; // Type of music context (OGG, XM, MOD)
+#if defined(SUPPORT_FILEFORMAT_OGG)
stb_vorbis *ctxOgg; // OGG audio context
+#endif
+#if defined(SUPPORT_FILEFORMAT_FLAC)
drflac *ctxFlac; // FLAC audio context
+#endif
+#if defined(SUPPORT_FILEFORMAT_XM)
jar_xm_context_t *ctxXm; // XM chiptune context
+#endif
+#if defined(SUPPORT_FILEFORMAT_MOD)
jar_mod_context_t ctxMod; // MOD chiptune context
+#endif
AudioStream stream; // Audio stream (double buffering)
@@ -163,13 +181,19 @@ typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_FILEFORMAT_WAV)
static Wave LoadWAV(const char *fileName); // Load WAV file
+#endif
+#if defined(SUPPORT_FILEFORMAT_OGG)
static Wave LoadOGG(const char *fileName); // Load OGG file
+#endif
+#if defined(SUPPORT_FILEFORMAT_FLAC)
static Wave LoadFLAC(const char *fileName); // Load FLAC file
+#endif
#if defined(AUDIO_STANDALONE)
-const char *GetExtension(const char *fileName); // Get the extension for a filename
-void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message (INFO, ERROR, WARNING)
+bool IsFileExtension(const char *fileName, const char *ext); // Check file extension
+void TraceLog(int msgType, const char *text, ...); // Outputs trace log message (INFO, ERROR, WARNING)
#endif
//----------------------------------------------------------------------------------
@@ -259,10 +283,15 @@ Wave LoadWave(const char *fileName)
{
Wave wave = { 0 };
- if (strcmp(GetExtension(fileName), "wav") == 0) wave = LoadWAV(fileName);
- else if (strcmp(GetExtension(fileName), "ogg") == 0) wave = LoadOGG(fileName);
- else if (strcmp(GetExtension(fileName), "flac") == 0) wave = LoadFLAC(fileName);
- else if (strcmp(GetExtension(fileName),"rres") == 0)
+ if (IsFileExtension(fileName, ".wav")) wave = LoadWAV(fileName);
+#if defined(SUPPORT_FILEFORMAT_OGG)
+ else if (IsFileExtension(fileName, ".ogg")) wave = LoadOGG(fileName);
+#endif
+#if defined(SUPPORT_FILEFORMAT_FLAC)
+ else if (IsFileExtension(fileName, ".flac")) wave = LoadFLAC(fileName);
+#endif
+#if !defined(AUDIO_STANDALONE)
+ else if (IsFileExtension(fileName, ".rres"))
{
RRES rres = LoadResource(fileName, 0);
@@ -273,7 +302,8 @@ Wave LoadWave(const char *fileName)
UnloadResource(rres);
}
- else TraceLog(WARNING, "[%s] File extension not recognized, it can't be loaded", fileName);
+#endif
+ else TraceLog(WARNING, "[%s] Audio fileformat not supported, it can't be loaded", fileName);
return wave;
}
@@ -540,7 +570,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
// NOTE: Only supported mono <--> stereo
if (wave->channels != channels)
{
- void *data = malloc(wave->sampleCount*channels*wave->sampleSize/8);
+ void *data = malloc(wave->sampleCount*wave->sampleSize/8*channels);
if ((wave->channels == 1) && (channels == 2)) // mono ---> stereo (duplicate mono information)
{
@@ -577,7 +607,7 @@ Wave WaveCopy(Wave wave)
{
Wave newWave = { 0 };
- newWave.data = malloc(wave.sampleCount*wave.channels*wave.sampleSize/8);
+ newWave.data = malloc(wave.sampleCount*wave.sampleSize/8*wave.channels);
if (newWave.data != NULL)
{
@@ -602,7 +632,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample)
{
int sampleCount = finalSample - initSample;
- void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8);
+ void *data = malloc(sampleCount*wave->sampleSize/8*wave->channels);
memcpy(data, (unsigned char*)wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8);
@@ -640,7 +670,7 @@ Music LoadMusicStream(const char *fileName)
{
Music music = (MusicData *)malloc(sizeof(MusicData));
- if (strcmp(GetExtension(fileName), "ogg") == 0)
+ if (IsFileExtension(fileName, ".ogg"))
{
// Open ogg audio stream
music->ctxOgg = stb_vorbis_open_filename(fileName, NULL, NULL);
@@ -663,7 +693,8 @@ Music LoadMusicStream(const char *fileName)
TraceLog(DEBUG, "[%s] OGG memory required: %i", fileName, info.temp_memory_required);
}
}
- else if (strcmp(GetExtension(fileName), "flac") == 0)
+#if defined(SUPPORT_FILEFORMAT_FLAC)
+ else if (IsFileExtension(fileName, ".flac"))
{
music->ctxFlac = drflac_open_file(fileName);
@@ -682,7 +713,9 @@ Music LoadMusicStream(const char *fileName)
TraceLog(DEBUG, "[%s] FLAC channels: %i", fileName, music->ctxFlac->channels);
}
}
- else if (strcmp(GetExtension(fileName), "xm") == 0)
+#endif
+#if defined(SUPPORT_FILEFORMAT_XM)
+ else if (IsFileExtension(fileName, ".xm"))
{
int result = jar_xm_create_context_from_file(&music->ctxXm, 48000, fileName);
@@ -702,7 +735,9 @@ Music LoadMusicStream(const char *fileName)
}
else TraceLog(WARNING, "[%s] XM file could not be opened", fileName);
}
- else if (strcmp(GetExtension(fileName), "mod") == 0)
+#endif
+#if defined(SUPPORT_FILEFORMAT_MOD)
+ else if (IsFileExtension(fileName, ".mod"))
{
jar_mod_init(&music->ctxMod);
@@ -719,7 +754,8 @@ Music LoadMusicStream(const char *fileName)
}
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);
+#endif
+ else TraceLog(WARNING, "[%s] Audio fileformat not supported, it can't be loaded", fileName);
return music;
}
@@ -730,9 +766,15 @@ void UnloadMusicStream(Music music)
CloseAudioStream(music->stream);
if (music->ctxType == MUSIC_AUDIO_OGG) stb_vorbis_close(music->ctxOgg);
+#if defined(SUPPORT_FILEFORMAT_FLAC)
else if (music->ctxType == MUSIC_AUDIO_FLAC) drflac_free(music->ctxFlac);
+#endif
+#if defined(SUPPORT_FILEFORMAT_XM)
else if (music->ctxType == MUSIC_MODULE_XM) jar_xm_free_context(music->ctxXm);
+#endif
+#if defined(SUPPORT_FILEFORMAT_MOD)
else if (music->ctxType == MUSIC_MODULE_MOD) jar_mod_unload(&music->ctxMod);
+#endif
free(music);
}
@@ -755,30 +797,46 @@ void ResumeMusicStream(Music music)
ALenum state;
alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state);
- if (state == AL_PAUSED) alSourcePlay(music->stream.source);
+ if (state == AL_PAUSED)
+ {
+ TraceLog(INFO, "[AUD ID %i] Resume music stream playing", music->stream.source);
+ alSourcePlay(music->stream.source);
+ }
}
// Stop music playing (close stream)
+// TODO: To clear a buffer, make sure they have been already processed!
void StopMusicStream(Music music)
{
alSourceStop(music->stream.source);
+ /*
// Clear stream buffers
+ // WARNING: Queued buffers must have been processed before unqueueing and reloaded with data!!!
void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, 1);
-
+
for (int i = 0; i < MAX_STREAM_BUFFERS; i++)
{
+ //UpdateAudioStream(music->stream, pcm, AUDIO_BUFFER_SIZE); // Update one buffer at a time
alBufferData(music->stream.buffers[i], music->stream.format, pcm, AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, music->stream.sampleRate);
}
free(pcm);
+ */
// Restart music context
switch (music->ctxType)
{
case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break;
+#if defined(SUPPORT_FILEFORMAT_FLAC)
+ case MUSIC_MODULE_FLAC: /* TODO: Restart FLAC context */ break;
+#endif
+#if defined(SUPPORT_FILEFORMAT_XM)
case MUSIC_MODULE_XM: /* TODO: Restart XM context */ break;
+#endif
+#if defined(SUPPORT_FILEFORMAT_MOD)
case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break;
+#endif
default: break;
}
@@ -797,14 +855,14 @@ void UpdateMusicStream(Music music)
if (processed > 0)
{
- bool active = true;
+ bool streamEnding = false;
// NOTE: Using dynamic allocation because it could require more than 16KB
- void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1);
+ void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.sampleSize/8*music->stream.channels, 1);
int numBuffersToProcess = processed;
int samplesCount = 0; // Total size of data steamed in L+R samples for xm floats,
- //individual L or R for ogg shorts
+ // individual L or R for ogg shorts
for (int i = 0; i < numBuffersToProcess; i++)
{
@@ -820,14 +878,20 @@ void UpdateMusicStream(Music music)
int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(music->ctxOgg, music->stream.channels, (short *)pcm, samplesCount*music->stream.channels);
} break;
+ #if defined(SUPPORT_FILEFORMAT_FLAC)
case MUSIC_AUDIO_FLAC:
{
// NOTE: Returns the number of samples to process
unsigned int numSamplesFlac = (unsigned int)drflac_read_s16(music->ctxFlac, samplesCount*music->stream.channels, (short *)pcm);
} break;
+ #endif
+ #if defined(SUPPORT_FILEFORMAT_XM)
case MUSIC_MODULE_XM: jar_xm_generate_samples_16bit(music->ctxXm, pcm, samplesCount); break;
+ #endif
+ #if defined(SUPPORT_FILEFORMAT_MOD)
case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, samplesCount, 0); break;
+ #endif
default: break;
}
@@ -836,16 +900,16 @@ void UpdateMusicStream(Music music)
if (music->samplesLeft <= 0)
{
- active = false;
+ streamEnding = true;
break;
}
}
-
- // This error is registered when UpdateAudioStream() fails
- if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data...");
+
+ // Free allocated pcm data
+ free(pcm);
// Reset audio stream for looping
- if (!active)
+ if (streamEnding)
{
StopMusicStream(music); // Stop music (and reset)
@@ -862,8 +926,6 @@ void UpdateMusicStream(Music music)
// just make sure to play again on window restore
if (state != AL_PLAYING) PlayMusicStream(music);
}
-
- free(pcm);
}
}
@@ -1010,7 +1072,8 @@ void CloseAudioStream(AudioStream stream)
}
// Update audio stream buffers with data
-// NOTE: Only updates one buffer per call
+// NOTE 1: Only updates one buffer of the stream source: unqueue -> update -> queue
+// NOTE 2: To unqueue a buffer it needs to be processed: IsAudioBufferProcessed()
void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
{
ALuint buffer = 0;
@@ -1019,9 +1082,10 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
// Check if any buffer was available for unqueue
if (alGetError() != AL_INVALID_VALUE)
{
- alBufferData(buffer, stream.format, data, samplesCount*stream.channels*stream.sampleSize/8, stream.sampleRate);
+ alBufferData(buffer, stream.format, data, samplesCount*stream.sampleSize/8*stream.channels, stream.sampleRate);
alSourceQueueBuffers(stream.source, 1, &buffer);
}
+ else TraceLog(WARNING, "[AUD ID %i] Audio buffer not available for unqueuing", stream.source);
}
// Check if any audio stream buffers requires refill
@@ -1066,6 +1130,7 @@ void StopAudioStream(AudioStream stream)
// Module specific Functions Definition
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_FILEFORMAT_WAV)
// Load WAV file into Wave structure
static Wave LoadWAV(const char *fileName)
{
@@ -1182,31 +1247,29 @@ static Wave LoadWAV(const char *fileName)
return wave;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_OGG)
// Load OGG file into Wave structure
// NOTE: Using stb_vorbis library
static Wave LoadOGG(const char *fileName)
{
- Wave wave;
+ Wave wave = { 0 };
stb_vorbis *oggFile = stb_vorbis_open_filename(fileName, NULL, NULL);
- if (oggFile == NULL)
- {
- TraceLog(WARNING, "[%s] OGG file could not be opened", fileName);
- wave.data = NULL;
- }
+ if (oggFile == NULL) TraceLog(WARNING, "[%s] OGG file could not be opened", fileName);
else
{
stb_vorbis_info info = stb_vorbis_get_info(oggFile);
-
+
wave.sampleRate = info.sample_rate;
wave.sampleSize = 16; // 16 bit per sample (short)
wave.channels = info.channels;
- wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile);
+ wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile); // Independent by channel
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
- 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);
+ if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio length is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
wave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short));
@@ -1222,7 +1285,9 @@ static Wave LoadOGG(const char *fileName)
return wave;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_FLAC)
// Load FLAC file into Wave structure
// NOTE: Using dr_flac library
static Wave LoadFLAC(const char *fileName)
@@ -1244,15 +1309,22 @@ static Wave LoadFLAC(const char *fileName)
return wave;
}
+#endif
// Some required functions for audio standalone module version
#if defined(AUDIO_STANDALONE)
-// Get the extension for a filename
-const char *GetExtension(const char *fileName)
+// Check file extension
+bool IsFileExtension(const char *fileName, const char *ext)
{
- const char *dot = strrchr(fileName, '.');
- if (!dot || dot == fileName) return "";
- return (dot + 1);
+ bool result = false;
+ const char *fileExt;
+
+ if ((fileExt = strrchr(fileName, '.')) != NULL)
+ {
+ if (strcmp(fileExt, ext) == 0) result = true;
+ }
+
+ return result;
}
// Outputs a trace log message (INFO, ERROR, WARNING)
@@ -1262,7 +1334,7 @@ void TraceLog(int msgType, const char *text, ...)
va_list args;
int traceDebugMsgs = 0;
-#ifdef DO_NOT_TRACE_DEBUG_MSGS
+#if defined(DO_NOT_TRACE_DEBUG_MSGS)
traceDebugMsgs = 0;
#endif
diff --git a/src/audio.h b/src/audio.h
index 01ed9f72..48ef7403 100644
--- a/src/audio.h
+++ b/src/audio.h
@@ -1,31 +1,37 @@
/**********************************************************************************************
*
-* raylib.audio
+* raylib.audio - Basic funtionality to work with audio
*
-* This module provides basic functionality to work with audio:
-* Manage audio device (init/close)
-* Load and Unload audio files (WAV, OGG, FLAC, XM, MOD)
-* Play/Stop/Pause/Resume loaded audio
-* Manage mixing channels
-* Manage raw audio context
+* FEATURES:
+* - Manage audio device (init/close)
+* - Load and unload audio files
+* - Format wave data (sample rate, size, channels)
+* - Play/Stop/Pause/Resume loaded audio
+* - Manage mixing channels
+* - Manage raw audio context
+*
+* LIMITATIONS:
+* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS)
+* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32)
*
* DEPENDENCIES:
* OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html)
* stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/)
-* jar_xm - XM module file loading
-* jar_mod - MOD audio file loading
-* dr_flac - FLAC audio file loading
+* jar_xm - XM module file loading (#define SUPPORT_FILEFORMAT_XM)
+* jar_mod - MOD audio file loading (#define SUPPORT_FILEFORMAT_MOD)
+* dr_flac - FLAC audio file loading (#define SUPPORT_FILEFORMAT_FLAC)
*
-* Many thanks to Joshua Reisenauer (github: @kd7tck) for the following additions:
-* XM audio module support (jar_xm)
-* MOD audio module support (jar_mod)
-* Mixing channels support
-* Raw audio context support
+* CONTRIBUTORS:
+* Joshua Reisenauer (github: @kd7tck):
+* - XM audio module support (jar_xm)
+* - MOD audio module support (jar_mod)
+* - Mixing channels support
+* - Raw audio context support
*
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -117,7 +123,7 @@ Wave LoadWave(const char *fileName); // Load wave dat
Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data
Sound LoadSound(const char *fileName); // Load sound from file
Sound LoadSoundFromWave(Wave wave); // Load sound from wave data
-void UpdateSound(Sound sound, const void *data, int samplesCount); // Update sound buffer with new data
+void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
void UnloadWave(Wave wave); // Unload wave data
void UnloadSound(Sound sound); // Unload sound
void PlaySound(Sound sound); // Play a sound
@@ -145,10 +151,11 @@ void SetMusicLoopCount(Music music, float count); // Set music loo
float GetMusicTimeLength(Music music); // Get music time length (in seconds)
float GetMusicTimePlayed(Music music); // Get current music time played (in seconds)
+// Raw audio stream functions
AudioStream InitAudioStream(unsigned int sampleRate,
- unsigned int sampleSize,
- unsigned int channels); // Init audio stream (to stream raw audio pcm data)
-void UpdateAudioStream(AudioStream stream, void *data, int samplesCount); // Update audio stream buffers with data
+ unsigned int sampleSize,
+ unsigned int channels); // Init audio stream (to stream raw audio pcm data)
+void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
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
diff --git a/src/camera.h b/src/camera.h
index 87ba1942..8067e7bf 100644
--- a/src/camera.h
+++ b/src/camera.h
@@ -1,6 +1,6 @@
/*******************************************************************************************
*
-* raylib Camera System - Camera Modes Setup and Control Functions
+* raylib.camera - Camera system with multiple modes support
*
* NOTE: Memory footprint of this library is aproximately 52 bytes (global variables)
*
@@ -22,7 +22,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2015-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2015-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -181,7 +181,14 @@ void SetCameraMoveControls(int frontKey, int backKey,
// 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;
+typedef enum {
+ MOVE_FRONT = 0,
+ MOVE_BACK,
+ MOVE_RIGHT,
+ MOVE_LEFT,
+ MOVE_UP,
+ MOVE_DOWN
+} CameraMove;
//----------------------------------------------------------------------------------
// Global Variables Definition
@@ -203,15 +210,14 @@ static int cameraMode = CAMERA_CUSTOM; // Current camera mode
#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 void EnableCursor() {} // Unlock cursor
+static void DisableCursor() {} // Lock cursor
+
+static int IsKeyDown(int key) { return 0; }
+
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; }
+static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
#endif
//----------------------------------------------------------------------------------
@@ -242,18 +248,23 @@ void SetCameraMode(Camera camera, int mode)
cameraAngle.y = -asinf(fabsf(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.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;
+
+ // Lock cursor for first person and third person cameras
+ if ((mode == CAMERA_FIRST_PERSON) ||
+ (mode == CAMERA_THIRD_PERSON)) DisableCursor();
+ else EnableCursor();
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()
+// System: EnableCursor(), DisableCursor()
+// Mouse: IsMouseButtonDown(), GetMousePosition(), GetMouseWheelMove()
// Keys: IsKeyDown()
// TODO: Port to quaternion-based camera
void UpdateCamera(Camera *camera)
@@ -284,36 +295,10 @@ void UpdateCamera(Camera *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 < (float)screenHeight/3.0f) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y });
- else if (mousePosition.y < (float)screenHeight/3.0f) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 });
- else if (mousePosition.x > (screenWidth - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y });
- else if (mousePosition.y > (screenHeight - (float)screenHeight/3.0f)) 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;
- }
+ 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();
+ previousMousePosition = mousePosition;
}
// Support for multiple automatic camera modes
diff --git a/src/core.c b/src/core.c
index a3b5f486..07f3bb07 100644
--- a/src/core.c
+++ b/src/core.c
@@ -2,7 +2,13 @@
*
* raylib.core - Basic functions to manage windows, OpenGL context and input on multiple platforms
*
-* The following platforms are supported: Windows, Linux, Mac (OSX), Android, Raspberry Pi, HTML5, Oculus Rift CV1
+* PLATFORMS SUPPORTED:
+* - Windows (win32/Win64)
+* - Linux (tested on Ubuntu)
+* - OSX (Mac)
+* - Android (ARM or ARM64)
+* - Raspberry Pi (Raspbian)
+* - HTML5 (Chrome, Firefox)
*
* CONFIGURATION:
*
@@ -22,17 +28,25 @@
* Windowing and input system configured for HTML5 (run on browser), code converted from C to asm.js
* using emscripten compiler. OpenGL ES 2.0 required for direct translation to WebGL equivalent code.
*
-* #define LOAD_DEFAULT_FONT (defined by default)
+* #define SUPPORT_DEFAULT_FONT (default)
* Default font is loaded on window initialization to be available for the user to render simple text.
* NOTE: If enabled, uses external module functions to load default raylib font (module: text)
*
-* #define INCLUDE_CAMERA_SYSTEM / SUPPORT_CAMERA_SYSTEM
+* #define SUPPORT_CAMERA_SYSTEM
+* Camera module is included (camera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
*
-* #define INCLUDE_GESTURES_SYSTEM / SUPPORT_GESTURES_SYSTEM
+* #define SUPPORT_GESTURES_SYSTEM
+* Gestures module is included (gestures.h) to support gestures detection: tap, hold, swipe, drag
*
* #define SUPPORT_MOUSE_GESTURES
* Mouse gestures are directly mapped like touches and processed by gestures system.
*
+* #define SUPPORT_BUSY_WAIT_LOOP
+* Use busy wait loop for timming sync, if not defined, a high-resolution timer is setup and used
+*
+* #define SUPPORT_GIF_RECORDING
+* Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
+*
* DEPENDENCIES:
* GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX)
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
@@ -42,7 +56,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -61,21 +75,38 @@
*
**********************************************************************************************/
+// Default configuration flags (supported features)
+//-------------------------------------------------
+#define SUPPORT_DEFAULT_FONT
+#define SUPPORT_MOUSE_GESTURES
+#define SUPPORT_CAMERA_SYSTEM
+#define SUPPORT_GESTURES_SYSTEM
+#define SUPPORT_BUSY_WAIT_LOOP
+#define SUPPORT_GIF_RECORDING
+//-------------------------------------------------
+
#include "raylib.h"
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
-#include "utils.h" // Required for: fopen() Android mapping, TraceLog()
+#include "utils.h" // Required for: fopen() Android mapping
#define RAYMATH_IMPLEMENTATION // Use raymath as a header-only library (includes implementation)
#define RAYMATH_EXTERN_INLINE // Compile raymath functions as static inline (remember, it's a compiler hint)
#include "raymath.h" // Required for: Vector3 and Matrix functions
-#define GESTURES_IMPLEMENTATION
-#include "gestures.h" // Gestures detection functionality
+#if defined(SUPPORT_GESTURES_SYSTEM)
+ #define GESTURES_IMPLEMENTATION
+ #include "gestures.h" // Gestures detection functionality
+#endif
-#if !defined(PLATFORM_ANDROID)
+#if defined(SUPPORT_CAMERA_SYSTEM) && !defined(PLATFORM_ANDROID)
#define CAMERA_IMPLEMENTATION
- #include "camera.h" // Camera system functionality
+ #include "camera.h" // Camera system functionality
+#endif
+
+#if defined(SUPPORT_GIF_RECORDING)
+ #define GIF_IMPLEMENTATION
+ #include "external/gif.h" // Support GIF recording
#endif
#include <stdio.h> // Standard input / output lib
@@ -83,12 +114,22 @@
#include <stdint.h> // Required for: typedef unsigned long long int uint64_t, used by hi-res timer
#include <time.h> // Required for: time() - Android/RPI hi-res timer (NOTE: Linux only!)
#include <math.h> // Required for: tan() [Used in Begin3dMode() to set perspective]
-#include <string.h> // Required for: strcmp()
+#include <string.h> // Required for: strrchr(), strcmp()
//#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
-#if defined __linux || defined(PLATFORM_WEB)
+#ifdef _WIN32
+ #include <direct.h> // Required for: _getch(), _chdir()
+ #define GETCWD _getcwd // NOTE: MSDN recommends not to use getcwd(), chdir()
+ #define CHDIR _chdir
+#else
+ #include "unistd.h" // Required for: getch(), chdir() (POSIX)
+ #define GETCWD getcwd
+ #define CHDIR chdir
+#endif
+
+#if defined(__linux__) || defined(PLATFORM_WEB)
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
-#elif defined __APPLE__
+#elif defined(__APPLE__)
#include <unistd.h> // Required for: usleep()
#endif
@@ -96,13 +137,19 @@
//#define GLFW_INCLUDE_NONE // Disable the standard OpenGL header inclusion on GLFW3
#include <GLFW/glfw3.h> // GLFW3 library: Windows, OpenGL context and Input management
- #ifdef __linux
+ #if defined(__linux__)
#define GLFW_EXPOSE_NATIVE_X11 // Linux specific definitions for getting
#define GLFW_EXPOSE_NATIVE_GLX // native functions like glfwGetX11Window
#include <GLFW/glfw3native.h> // which are required for hiding mouse
#endif
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
+
+ #if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
+ // NOTE: Those functions require linking with winmm library
+ __stdcall unsigned int timeBeginPeriod(unsigned int uPeriod);
+ __stdcall unsigned int timeEndPeriod(unsigned int uPeriod);
+ #endif
#endif
#if defined(PLATFORM_ANDROID)
@@ -140,8 +187,6 @@
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
-#define STORAGE_FILENAME "storage.data"
-
#if defined(PLATFORM_RPI)
// Old device inputs system
#define DEFAULT_KEYBOARD_DEV STDIN_FILENO // Standard input
@@ -161,7 +206,7 @@
#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
-#define LOAD_DEFAULT_FONT // Load default font on window initialization (module: text)
+#define STORAGE_FILENAME "storage.data"
//----------------------------------------------------------------------------------
// Types and Structures Definition
@@ -233,6 +278,7 @@ static Matrix downscaleView; // Matrix to downscale view (in case
static const char *windowTitle; // Window text title...
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
static bool cursorHidden = false; // Track if cursor is hidden
+static int screenshotCounter = 0; // Screenshots counter
// Register mouse states
static char previousMouseState[3] = { 0 }; // Registers previous mouse button state
@@ -259,7 +305,14 @@ static int lastGamepadButtonPressed = -1; // Register last gamepad button pres
static int gamepadAxisCount = 0; // Register number of available gamepad axis
static Vector2 mousePosition; // Mouse position on screen
+
+#if defined(PLATFORM_WEB)
+static bool toggleCursorLock = false; // Ask for cursor pointer lock on next click
+#endif
+
+#if defined(SUPPORT_GESTURES_SYSTEM)
static Vector2 touchPosition[MAX_TOUCH_POINTS]; // Touch position on screen
+#endif
#if defined(PLATFORM_DESKTOP)
static char **dropFilesPath; // Store dropped files paths as strings
@@ -274,10 +327,16 @@ static double targetTime = 0.0; // Desired time for one frame, if 0
static char configFlags = 0; // Configuration flags (bit based)
static bool showLogo = false; // Track if showing logo at init is enabled
+#if defined(SUPPORT_GIF_RECORDING)
+static GifWriter gifWriter;
+static int gifFramesCounter = 0;
+static bool gifRecording = false;
+#endif
+
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by core)
//----------------------------------------------------------------------------------
-#if defined(LOAD_DEFAULT_FONT)
+#if defined(SUPPORT_DEFAULT_FONT)
extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow()
extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory
#endif
@@ -296,9 +355,6 @@ static void PollInputEvents(void); // Register user events
static void SwapBuffers(void); // Copy back buffer to front buffers
static void LogoAnimation(void); // Plays raylib logo appearing animation
static void SetupViewport(void); // Set viewport parameters
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
-static void TakeScreenshot(void); // Takes a screenshot and saves it in the same folder as executable
-#endif
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
@@ -323,7 +379,9 @@ 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);
-static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
+static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData);
+static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData);
+static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadEvent *gamepadEvent, void *userData);
#endif
@@ -348,7 +406,7 @@ static void *GamepadThread(void *arg); // Mouse reading thread
// Module Functions Definition - Window and OpenGL Context Functions
//----------------------------------------------------------------------------------
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-// Initialize Window and Graphics Context (OpenGL)
+// Initialize window and OpenGL context
void InitWindow(int width, int height, const char *title)
{
TraceLog(INFO, "Initializing raylib (v1.7.0)");
@@ -359,7 +417,7 @@ void InitWindow(int width, int height, const char *title)
// Init graphics device (display device and OpenGL context)
InitGraphicsDevice(width, height);
-#if defined(LOAD_DEFAULT_FONT)
+#if defined(SUPPORT_DEFAULT_FONT)
// Load default font
// NOTE: External function (defined in module: text)
LoadDefaultFont();
@@ -378,16 +436,22 @@ void InitWindow(int width, int height, const char *title)
#if defined(PLATFORM_WEB)
emscripten_set_fullscreenchange_callback(0, 0, 1, EmscriptenFullscreenChangeCallback);
-
- // NOTE: Some code examples
+
+ // Support keyboard events
+ emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback);
+
+ // Support mouse events
+ emscripten_set_click_callback("#canvas", NULL, 1, EmscriptenMouseCallback);
+
+ // Support touch events
+ emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
+ emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
+ emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
+ emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenTouchCallback);
//emscripten_set_touchstart_callback(0, NULL, 1, Emscripten_HandleTouch);
//emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
- emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenInputCallback);
- emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback);
- emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback);
- emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback);
- // Support gamepad (not provided by GLFW3 on emscripten)
+ // Support gamepad events (not provided by GLFW3 on emscripten)
emscripten_set_gamepadconnected_callback(NULL, 1, EmscriptenGamepadCallback);
emscripten_set_gamepaddisconnected_callback(NULL, 1, EmscriptenGamepadCallback);
#endif
@@ -405,7 +469,7 @@ void InitWindow(int width, int height, const char *title)
#endif
#if defined(PLATFORM_ANDROID)
-// Android activity initialization
+// Initialize Android activity
void InitWindow(int width, int height, void *state)
{
TraceLog(INFO, "Initializing raylib (v1.7.0)");
@@ -468,10 +532,18 @@ void InitWindow(int width, int height, void *state)
}
#endif
-// Close Window and Terminate Context
+// Close window and unload OpenGL context
void CloseWindow(void)
{
-#if defined(LOAD_DEFAULT_FONT)
+#if defined(SUPPORT_GIF_RECORDING)
+ if (gifRecording)
+ {
+ GifEnd(&gifWriter);
+ gifRecording = false;
+ }
+#endif
+
+#if defined(SUPPORT_DEFAULT_FONT)
UnloadDefaultFont();
#endif
@@ -482,6 +554,10 @@ void CloseWindow(void)
glfwTerminate();
#endif
+#if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
+ timeEndPeriod(1); // Restore time period
+#endif
+
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
// Close surface, context and display
if (display != EGL_NO_DISPLAY)
@@ -520,7 +596,7 @@ void CloseWindow(void)
TraceLog(INFO, "Window closed successfully");
}
-// Detect if KEY_ESCAPE pressed or Close icon pressed
+// Check if KEY_ESCAPE pressed or Close icon pressed
bool WindowShouldClose(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
@@ -535,7 +611,7 @@ bool WindowShouldClose(void)
#endif
}
-// Detect if window has been minimized (or lost focus)
+// Check if window has been minimized (or lost focus)
bool IsWindowMinimized(void)
{
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
@@ -545,7 +621,7 @@ bool IsWindowMinimized(void)
#endif
}
-// Fullscreen toggle (only PLATFORM_DESKTOP)
+// Toggle fullscreen mode (only PLATFORM_DESKTOP)
void ToggleFullscreen(void)
{
#if defined(PLATFORM_DESKTOP)
@@ -583,12 +659,15 @@ void SetWindowIcon(Image image)
// Set window position on screen (windowed mode)
void SetWindowPosition(int x, int y)
{
+#if defined(PLATFORM_DESKTOP)
glfwSetWindowPos(window, x, y);
+#endif
}
// Set monitor for the current window (fullscreen mode)
void SetWindowMonitor(int monitor)
{
+#if defined(PLATFORM_DESKTOP)
int monitorCount;
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount);
@@ -598,6 +677,16 @@ void SetWindowMonitor(int monitor)
TraceLog(INFO, "Selected fullscreen monitor: [%i] %s", monitor, glfwGetMonitorName(monitors[monitor]));
}
else TraceLog(WARNING, "Selected monitor not found");
+#endif
+}
+
+// Set window minimum dimensions (FLAG_WINDOW_RESIZABLE)
+void SetWindowMinSize(int width, int height)
+{
+#if defined(PLATFORM_DESKTOP)
+ const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
+ glfwSetWindowSizeLimits(window, width, height, mode->width, mode->height);
+#endif
}
// Get current screen width
@@ -617,7 +706,7 @@ int GetScreenHeight(void)
void ShowCursor()
{
#if defined(PLATFORM_DESKTOP)
- #ifdef __linux
+ #if defined(__linux__)
XUndefineCursor(glfwGetX11Display(), glfwGetX11Window(window));
#else
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
@@ -626,11 +715,11 @@ void ShowCursor()
cursorHidden = false;
}
-// Hide mouse cursor
+// Hides mouse cursor
void HideCursor()
{
#if defined(PLATFORM_DESKTOP)
- #ifdef __linux
+ #if defined(__linux__)
XColor col;
const char nil[] = {0};
@@ -646,39 +735,45 @@ void HideCursor()
cursorHidden = true;
}
-// Check if mouse cursor is hidden
+// Check if cursor is not visible
bool IsCursorHidden()
{
return cursorHidden;
}
-// Enable mouse cursor
+// Enables cursor (unlock cursor)
void EnableCursor()
{
#if defined(PLATFORM_DESKTOP)
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
#endif
+#if defined(PLATFORM_WEB)
+ toggleCursorLock = true;
+#endif
cursorHidden = false;
}
-// Disable mouse cursor
+// Disables cursor (lock cursor)
void DisableCursor()
{
#if defined(PLATFORM_DESKTOP)
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
#endif
+#if defined(PLATFORM_WEB)
+ toggleCursorLock = true;
+#endif
cursorHidden = true;
}
#endif // !defined(PLATFORM_ANDROID)
-// Sets Background Color
+// Set background color (framebuffer clear color)
void ClearBackground(Color color)
{
// Clear full framebuffer (not only render area) to color
rlClearColor(color.r, color.g, color.b, color.a);
}
-// Setup drawing canvas to start drawing
+// Setup canvas (framebuffer) to start drawing
void BeginDrawing(void)
{
currentTime = GetTime(); // Number of elapsed seconds since InitTimer() was called
@@ -693,11 +788,40 @@ void BeginDrawing(void)
// NOTE: Not required with OpenGL 3.3+
}
-// End canvas drawing and Swap Buffers (Double Buffering)
+// End canvas drawing and swap buffers (double buffering)
void EndDrawing(void)
{
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
+#if defined(SUPPORT_GIF_RECORDING)
+
+ #define GIF_RECORD_FRAMERATE 10
+
+ if (gifRecording)
+ {
+ gifFramesCounter++;
+
+ // NOTE: We record one gif frame every 10 game frames
+ if ((gifFramesCounter%GIF_RECORD_FRAMERATE) == 0)
+ {
+ // Get image data for the current frame (from backbuffer)
+ // NOTE: This process is very slow... :(
+ unsigned char *screenData = rlglReadScreenPixels(screenWidth, screenHeight);
+ GifWriteFrame(&gifWriter, screenData, screenWidth, screenHeight, 10, 8, false);
+
+ free(screenData); // Free image data
+ }
+
+ if (((gifFramesCounter/15)%2) == 1)
+ {
+ DrawCircle(30, screenHeight - 20, 10, RED);
+ DrawText("RECORDING", 50, screenHeight - 25, 10, MAROON);
+ }
+
+ rlglDraw(); // Draw RECORDING message
+ }
+#endif
+
SwapBuffers(); // Copy back buffer to front buffer
PollInputEvents(); // Poll user events
@@ -721,7 +845,7 @@ void EndDrawing(void)
}
}
-// Initialize 2D mode with custom camera
+// Initialize 2D mode with custom camera (2D)
void Begin2dMode(Camera2D camera)
{
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
@@ -739,7 +863,7 @@ void Begin2dMode(Camera2D camera)
rlMultMatrixf(MatrixToFloat(matTransform));
}
-// Ends 2D mode custom camera usage
+// Ends 2D mode with custom camera
void End2dMode(void)
{
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
@@ -747,15 +871,12 @@ void End2dMode(void)
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
}
-// Initializes 3D mode for drawing (Camera setup)
+// Initializes 3D mode with custom camera (3D)
void Begin3dMode(Camera camera)
{
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
-
- if (IsVrDeviceReady() || IsVrSimulator()) 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)
@@ -782,8 +903,6 @@ void End3dMode(void)
{
rlglDraw(); // Process internal buffers (update + draw)
- if (IsVrDeviceReady() || IsVrSimulator()) EndVrDrawing();
-
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
@@ -841,7 +960,107 @@ void EndTextureMode(void)
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
}
-// Set target FPS for the game
+// 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.
+ // For example, if you get view matrix, transpose and inverted and you transform it
+ // 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);
+
+#else // OPTION 2: Compute unprojection directly here
+
+ // 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 qNear = { deviceCoords.x, deviceCoords.y, 0.0f, 1.0f };
+ Quaternion qFar = { deviceCoords.x, deviceCoords.y, 1.0f, 1.0f };
+
+ // Multiply points by unproject matrix
+ QuaternionTransform(&qNear, matProjView);
+ QuaternionTransform(&qFar, matProjView);
+
+ // Calculate normalized world points in vectors
+ Vector3 nearPoint = { qNear.x/qNear.w, qNear.y/qNear.w, qNear.z/qNear.w};
+ Vector3 farPoint = { qFar.x/qFar.w, qFar.y/qFar.w, qFar.z/qFar.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.w };
+
+ // 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;
+}
+
+// Get transform matrix for camera
+Matrix GetCameraMatrix(Camera camera)
+{
+ return MatrixLookAt(camera.position, camera.target, camera.up);
+}
+
+// Set target FPS (maximum)
void SetTargetFPS(int fps)
{
if (fps < 1) targetTime = 0.0;
@@ -856,7 +1075,7 @@ int GetFPS(void)
return (int)(1.0f/GetFrameTime());
}
-// Returns time in seconds for one frame
+// Returns time in seconds for last frame drawn
float GetFrameTime(void)
{
// NOTE: We round value to milliseconds
@@ -888,7 +1107,6 @@ float *VectorToFloat(Vector3 vec)
return buffer;
}
-// Converts Matrix to float array
// 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
@@ -948,7 +1166,7 @@ int GetRandomValue(int min, int max)
return (rand()%(abs(max-min)+1) + min);
}
-// Fades color by a percentadge
+// Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
Color Fade(Color color, float alpha)
{
if (alpha < 0.0f) alpha = 0.0f;
@@ -959,7 +1177,13 @@ Color Fade(Color color, float alpha)
return (Color){color.r, color.g, color.b, (unsigned char)colorAlpha};
}
-// Enable some window/system configurations
+// Activate raylib logo at startup (can be done with flags)
+void ShowLogo(void)
+{
+ showLogo = true;
+}
+
+// Setup window configuration flags (view FLAGS)
void SetConfigFlags(char flags)
{
configFlags = flags;
@@ -968,21 +1192,74 @@ void SetConfigFlags(char flags)
if (configFlags & FLAG_FULLSCREEN_MODE) fullscreen = true;
}
-// Activates raylib logo at startup
-void ShowLogo(void)
+// NOTE TraceLog() function is located in [utils.h]
+
+// Takes a screenshot of current screen (saved a .png)
+void TakeScreenshot(const char *fileName)
{
- showLogo = true;
+#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+ unsigned char *imgData = rlglReadScreenPixels(renderWidth, renderHeight);
+ SavePNG(fileName, imgData, renderWidth, renderHeight, 4); // Save image as PNG
+ free(imgData);
+
+ TraceLog(INFO, "Screenshot taken: %s", fileName);
+#endif
+}
+
+// Check file extension
+bool IsFileExtension(const char *fileName, const char *ext)
+{
+ bool result = false;
+ const char *fileExt;
+
+ if ((fileExt = strrchr(fileName, '.')) != NULL)
+ {
+ if (strcmp(fileExt, ext) == 0) result = true;
+ }
+
+ return result;
+}
+
+// Get directory for a given fileName (with path)
+const char *GetDirectoryPath(const char *fileName)
+{
+ char *lastSlash = NULL;
+ static char filePath[256]; // MAX_DIRECTORY_PATH_SIZE = 256
+ memset(filePath, 0, 256);
+
+ lastSlash = strrchr(fileName, '\\');
+ strncpy(filePath, fileName, strlen(fileName) - (strlen(lastSlash) - 1));
+ filePath[strlen(fileName) - strlen(lastSlash)] = '\0';
+
+ return filePath;
+}
+
+// Get current working directory
+const char *GetWorkingDirectory(void)
+{
+ static char currentDir[256]; // MAX_DIRECTORY_PATH_SIZE = 256
+ memset(currentDir, 0, 256);
+
+ GETCWD(currentDir, 256 - 1);
+
+ return currentDir;
+}
+
+// Change working directory, returns true if success
+bool ChangeDirectory(const char *dir)
+{
+ return (CHDIR(dir) == 0);
}
#if defined(PLATFORM_DESKTOP)
-// Check if a file have been dropped into window
+// Check if a file has been dropped into window
bool IsFileDropped(void)
{
if (dropFilesCount > 0) return true;
else return false;
}
-// Retrieve dropped files into window
+// Get dropped files names
char **GetDroppedFiles(int *count)
{
*count = dropFilesCount;
@@ -1003,7 +1280,7 @@ void ClearDroppedFiles(void)
}
#endif
-// Storage save integer value (to defined position)
+// Save integer value to storage file (to defined position)
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
void StorageSaveValue(int position, int value)
{
@@ -1043,7 +1320,7 @@ void StorageSaveValue(int position, int value)
}
}
-// Storage load integer value (from defined position)
+// Load integer value from storage file (from defined position)
// NOTE: If requested position could not be found, value 0 is returned
int StorageLoadValue(int position)
{
@@ -1082,106 +1359,6 @@ int StorageLoadValue(int position)
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.
- // For example, if you get view matrix, transpose and inverted and you transform it
- // 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);
-
-#else // OPTION 2: Compute unprojection directly here
-
- // 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.w };
-
- // 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;
-}
-
-// Get transform matrix for camera
-Matrix GetCameraMatrix(Camera camera)
-{
- return MatrixLookAt(camera.position, camera.target, camera.up);
-}
-
//----------------------------------------------------------------------------------
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
//----------------------------------------------------------------------------------
@@ -1467,7 +1644,7 @@ int GetMouseWheelMove(void)
#endif
}
-// Returns touch position X
+// Returns touch position X for touch point 0 (relative to screen size)
int GetTouchX(void)
{
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
@@ -1477,7 +1654,7 @@ int GetTouchX(void)
#endif
}
-// Returns touch position Y
+// Returns touch position Y for touch point 0 (relative to screen size)
int GetTouchY(void)
{
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
@@ -1487,7 +1664,7 @@ int GetTouchY(void)
#endif
}
-// Returns touch position XY
+// Returns touch position XY for a touch point index (relative to screen size)
// TODO: Touch position should be scaled depending on display size and render size
Vector2 GetTouchPosition(int index)
{
@@ -1597,7 +1774,7 @@ static void InitGraphicsDevice(int width, int height)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
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__
+#if defined(__APPLE__)
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!
@@ -1739,12 +1916,13 @@ static void InitGraphicsDevice(int width, int height)
const EGLint framebufferAttribs[] =
{
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI?
- //EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android!
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI?
+ //EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // Don't use it on Android!
EGL_RED_SIZE, 8, // RED color bit depth (alternative: 5)
EGL_GREEN_SIZE, 8, // GREEN color bit depth (alternative: 6)
EGL_BLUE_SIZE, 8, // BLUE color bit depth (alternative: 5)
- //EGL_ALPHA_SIZE, 8, // ALPHA bit depth
+ //EGL_ALPHA_SIZE, 8, // ALPHA bit depth (required for transparent framebuffer)
+ //EGL_TRANSPARENT_TYPE, EGL_NONE, // Request transparent framebuffer (EGL_TRANSPARENT_RGB does not work on RPI)
EGL_DEPTH_SIZE, 16, // Depth buffer size (Required to use Depth testing!)
//EGL_STENCIL_SIZE, 8, // Stencil buffer size
EGL_SAMPLE_BUFFERS, sampleBuffer, // Activate MSAA
@@ -1819,7 +1997,7 @@ static void InitGraphicsDevice(int width, int height)
VC_DISPMANX_ALPHA_T alpha;
alpha.flags = DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
- alpha.opacity = 255;
+ alpha.opacity = 255; // Set transparency level for framebuffer, requires EGLAttrib: EGL_TRANSPARENT_TYPE
alpha.mask = 0;
dispmanDisplay = vc_dispmanx_display_open(0); // LCD
@@ -1882,7 +2060,7 @@ static void InitGraphicsDevice(int width, int height)
// Set viewport parameters
static void SetupViewport(void)
{
-#ifdef __APPLE__
+#if defined(__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.
@@ -1974,6 +2152,10 @@ static void SetupFramebufferSize(int displayWidth, int displayHeight)
static void InitTimer(void)
{
srand(time(NULL)); // Initialize random seed
+
+#if !defined(SUPPORT_BUSY_WAIT_LOOP) && defined(_WIN32)
+ timeBeginPeriod(1); // Setup high-resolution timer to 1ms (granularity of 1-2 ms)
+#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
struct timespec now;
@@ -2005,9 +2187,11 @@ static double GetTime(void)
}
// Wait for some milliseconds (stop program execution)
+// NOTE: Sleep() granularity could be around 10 ms, it means, Sleep() could
+// take longer than expected... for that reason we use the busy wait loop
+// http://stackoverflow.com/questions/43057578/c-programming-win32-games-sleep-taking-longer-than-expected
static void Wait(float ms)
{
-#define SUPPORT_BUSY_WAIT_LOOP
#if defined(SUPPORT_BUSY_WAIT_LOOP)
double prevTime = GetTime();
double nextTime = 0.0;
@@ -2015,9 +2199,9 @@ static void Wait(float ms)
// Busy wait loop
while ((nextTime - prevTime) < ms/1000.0f) nextTime = GetTime();
#else
- #if defined _WIN32
- Sleep(ms);
- #elif defined __linux || defined(PLATFORM_WEB)
+ #if defined(_WIN32)
+ Sleep((unsigned int)ms);
+ #elif defined(__linux__) || defined(PLATFORM_WEB)
struct timespec req = { 0 };
time_t sec = (int)(ms/1000.0f);
ms -= (sec*1000);
@@ -2026,7 +2210,7 @@ static void Wait(float ms)
// NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated.
while (nanosleep(&req, &req) == -1) continue;
- #elif defined __APPLE__
+ #elif defined(__APPLE__)
usleep(ms*1000.0f);
#endif
#endif
@@ -2065,9 +2249,11 @@ static bool GetMouseButtonStatus(int button)
// Poll (store) all input events
static void PollInputEvents(void)
{
+#if defined(SUPPORT_GESTURES_SYSTEM)
// NOTE: Gestures update must be called every frame to reset gestures correctly
// because ProcessGestureEvent() is just called on an event, not every frame
UpdateGestures();
+#endif
// Reset last key pressed registered
lastKeyPressed = -1;
@@ -2238,28 +2424,6 @@ static void SwapBuffers(void)
#endif
}
-#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
-// Takes a screenshot and saves it in the same folder as executable
-static void TakeScreenshot(void)
-{
- static int shotNum = 0; // Screenshot number, increments every screenshot take during program execution
- char buffer[20]; // Buffer to store file name
-
- unsigned char *imgData = rlglReadScreenPixels(renderWidth, renderHeight);
-
- sprintf(buffer, "screenshot%03i.png", shotNum);
-
- // Save image as PNG
- SavePNG(buffer, imgData, renderWidth, renderHeight, 4);
-
- free(imgData);
-
- shotNum++;
-
- TraceLog(INFO, "[%s] Screenshot taken!", buffer);
-}
-#endif
-
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
// GLFW3 Error Callback, runs on GLFW3 error
static void ErrorCallback(int error, const char *description)
@@ -2283,8 +2447,39 @@ 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();
-#endif
+ else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
+ {
+ #if defined(SUPPORT_GIF_RECORDING)
+ if (mods == GLFW_MOD_CONTROL)
+ {
+ if (gifRecording)
+ {
+ GifEnd(&gifWriter);
+ gifRecording = false;
+
+ TraceLog(INFO, "End animated GIF recording");
+ }
+ else
+ {
+ gifRecording = true;
+ gifFramesCounter = 0;
+
+ // NOTE: delay represents the time between frames in the gif, if we capture a gif frame every
+ // 10 game frames and each frame trakes 16.6ms (60fps), delay between gif frames should be ~16.6*10.
+ GifBegin(&gifWriter, FormatText("screenrec%03i.gif", screenshotCounter), screenWidth, screenHeight, (int)(GetFrameTime()*10.0f), 8, false);
+ screenshotCounter++;
+
+ TraceLog(INFO, "Begin animated GIF recording: %s", FormatText("screenrec%03i.gif", screenshotCounter));
+ }
+ }
+ else
+ #endif // SUPPORT_GIF_RECORDING
+ {
+ TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
+ screenshotCounter++;
+ }
+ }
+#endif // PLATFORM_DESKTOP
else
{
currentKeyState[key] = action;
@@ -2297,8 +2492,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
{
currentMouseState[button] = action;
-#define ENABLE_MOUSE_GESTURES
-#if defined(ENABLE_MOUSE_GESTURES)
+#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
// Process mouse events as touches to be able to use mouse-gestures
GestureEvent gestureEvent;
@@ -2329,8 +2523,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
// GLFW3 Cursor Position Callback, runs on mouse move
static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
{
-#define ENABLE_MOUSE_GESTURES
-#if defined(ENABLE_MOUSE_GESTURES)
+#if defined(SUPPORT_GESTURES_SYSTEM) && defined(SUPPORT_MOUSE_GESTURES)
// Process mouse events as touches to be able to use mouse-gestures
GestureEvent gestureEvent;
@@ -2460,7 +2653,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Init graphics device (display device and OpenGL context)
InitGraphicsDevice(screenWidth, screenHeight);
- #if defined(LOAD_DEFAULT_FONT)
+ #if defined(SUPPORT_DEFAULT_FONT)
// Load default font
// NOTE: External function (defined in module: text)
LoadDefaultFont();
@@ -2664,8 +2857,42 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte
return 0;
}
+// Register keyboard input events
+static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData)
+{
+ if ((eventType == EMSCRIPTEN_EVENT_KEYPRESS) && (strcmp(keyEvent->code, "Escape") == 0))
+ {
+ emscripten_exit_pointerlock();
+ }
+
+ return 0;
+}
+
+// Register mouse input events
+static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData)
+{
+ // Lock mouse pointer when click on screen
+ if ((eventType == EMSCRIPTEN_EVENT_CLICK) && toggleCursorLock)
+ {
+ EmscriptenPointerlockChangeEvent plce;
+ emscripten_get_pointerlock_status(&plce);
+
+ if (!plce.isActive) emscripten_request_pointerlock(0, 1);
+ else
+ {
+ emscripten_exit_pointerlock();
+ emscripten_get_pointerlock_status(&plce);
+ //if (plce.isActive) TraceLog(WARNING, "Pointer lock exit did not work!");
+ }
+
+ toggleCursorLock = false;
+ }
+
+ return 0;
+}
+
// Register touch input events
-static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
+static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
{
/*
for (int i = 0; i < touchEvent->numTouches; i++)
@@ -2891,8 +3118,12 @@ static void ProcessKeyboard(void)
// 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)
+ // Check screen capture key (raylib key: KEY_F12)
+ if (currentKeyState[301] == 1)
+ {
+ TakeScreenshot(FormatText("screenshot%03i.png", screenshotCounter));
+ screenshotCounter++;
+ }
}
// Restore default keyboard input
@@ -3179,7 +3410,7 @@ static void *GamepadThread(void *arg)
// Plays raylib logo appearing animation
static void LogoAnimation(void)
{
-#ifndef PLATFORM_WEB
+#if !defined(PLATFORM_WEB)
int logoPositionX = screenWidth/2 - 128;
int logoPositionY = screenHeight/2 - 128;
diff --git a/src/easings.h b/src/easings.h
index 527970ab..9ad27313 100644
--- a/src/easings.h
+++ b/src/easings.h
@@ -122,7 +122,7 @@ EASEDEF float EaseCubicOut(float t, float b, float c, float d) { return (c*((t=t
EASEDEF float EaseCubicInOut(float t, float b, float c, float d)
{
if ((t/=d/2) < 1) return (c/2*t*t*t + b);
- return (c/2*((t-=2)*t*t + 2) + b);
+ return (c/2*((t-=2)*t*t + 2) + b);
}
// Quadratic Easing functions
diff --git a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_CAPI_Util.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_CAPI_Util.h
deleted file mode 100644
index 552f3b12..00000000
--- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_CAPI_Util.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/********************************************************************************//**
-\file OVR_CAPI_Util.h
-\brief This header provides LibOVR utility function declarations
-\copyright Copyright 2015-2016 Oculus VR, LLC All Rights reserved.
-*************************************************************************************/
-
-#ifndef OVR_CAPI_Util_h
-#define OVR_CAPI_Util_h
-
-
-#include "../OVR_CAPI.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/// Enumerates modifications to the projection matrix based on the application's needs.
-///
-/// \see ovrMatrix4f_Projection
-///
-typedef enum ovrProjectionModifier_
-{
- /// Use for generating a default projection matrix that is:
- /// * Right-handed.
- /// * Near depth values stored in the depth buffer are smaller than far depth values.
- /// * Both near and far are explicitly defined.
- /// * With a clipping range that is (0 to w).
- ovrProjection_None = 0x00,
-
- /// Enable if using left-handed transformations in your application.
- ovrProjection_LeftHanded = 0x01,
-
- /// After the projection transform is applied, far values stored in the depth buffer will be less than closer depth values.
- /// NOTE: Enable only if the application is using a floating-point depth buffer for proper precision.
- ovrProjection_FarLessThanNear = 0x02,
-
- /// When this flag is used, the zfar value pushed into ovrMatrix4f_Projection() will be ignored
- /// NOTE: Enable only if ovrProjection_FarLessThanNear is also enabled where the far clipping plane will be pushed to infinity.
- ovrProjection_FarClipAtInfinity = 0x04,
-
- /// Enable if the application is rendering with OpenGL and expects a projection matrix with a clipping range of (-w to w).
- /// Ignore this flag if your application already handles the conversion from D3D range (0 to w) to OpenGL.
- ovrProjection_ClipRangeOpenGL = 0x08,
-} ovrProjectionModifier;
-
-
-/// Return values for ovr_Detect.
-///
-/// \see ovr_Detect
-///
-typedef struct OVR_ALIGNAS(8) ovrDetectResult_
-{
- /// Is ovrFalse when the Oculus Service is not running.
- /// This means that the Oculus Service is either uninstalled or stopped.
- /// IsOculusHMDConnected will be ovrFalse in this case.
- /// Is ovrTrue when the Oculus Service is running.
- /// This means that the Oculus Service is installed and running.
- /// IsOculusHMDConnected will reflect the state of the HMD.
- ovrBool IsOculusServiceRunning;
-
- /// Is ovrFalse when an Oculus HMD is not detected.
- /// If the Oculus Service is not running, this will be ovrFalse.
- /// Is ovrTrue when an Oculus HMD is detected.
- /// This implies that the Oculus Service is also installed and running.
- ovrBool IsOculusHMDConnected;
-
- OVR_UNUSED_STRUCT_PAD(pad0, 6) ///< \internal struct padding
-
-} ovrDetectResult;
-
-OVR_STATIC_ASSERT(sizeof(ovrDetectResult) == 8, "ovrDetectResult size mismatch");
-
-
-/// Detects Oculus Runtime and Device Status
-///
-/// Checks for Oculus Runtime and Oculus HMD device status without loading the LibOVRRT
-/// shared library. This may be called before ovr_Initialize() to help decide whether or
-/// not to initialize LibOVR.
-///
-/// \param[in] timeoutMilliseconds Specifies a timeout to wait for HMD to be attached or 0 to poll.
-///
-/// \return Returns an ovrDetectResult object indicating the result of detection.
-///
-/// \see ovrDetectResult
-///
-OVR_PUBLIC_FUNCTION(ovrDetectResult) ovr_Detect(int timeoutMilliseconds);
-
-// On the Windows platform,
-#ifdef _WIN32
- /// This is the Windows Named Event name that is used to check for HMD connected state.
- #define OVR_HMD_CONNECTED_EVENT_NAME L"OculusHMDConnected"
-#endif // _WIN32
-
-
-/// Used to generate projection from ovrEyeDesc::Fov.
-///
-/// \param[in] fov Specifies the ovrFovPort to use.
-/// \param[in] znear Distance to near Z limit.
-/// \param[in] zfar Distance to far Z limit.
-/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags.
-///
-/// \return Returns the calculated projection matrix.
-///
-/// \see ovrProjectionModifier
-///
-OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags);
-
-
-/// Extracts the required data from the result of ovrMatrix4f_Projection.
-///
-/// \param[in] projection Specifies the project matrix from which to extract ovrTimewarpProjectionDesc.
-/// \param[in] projectionModFlags A combination of the ovrProjectionModifier flags.
-/// \return Returns the extracted ovrTimewarpProjectionDesc.
-/// \see ovrTimewarpProjectionDesc
-///
-OVR_PUBLIC_FUNCTION(ovrTimewarpProjectionDesc) ovrTimewarpProjectionDesc_FromProjection(ovrMatrix4f projection, unsigned int projectionModFlags);
-
-
-/// Generates an orthographic sub-projection.
-///
-/// Used for 2D rendering, Y is down.
-///
-/// \param[in] projection The perspective matrix that the orthographic matrix is derived from.
-/// \param[in] orthoScale Equal to 1.0f / pixelsPerTanAngleAtCenter.
-/// \param[in] orthoDistance Equal to the distance from the camera in meters, such as 0.8m.
-/// \param[in] HmdToEyeOffsetX Specifies the offset of the eye from the center.
-///
-/// \return Returns the calculated projection matrix.
-///
-OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale,
- float orthoDistance, float HmdToEyeOffsetX);
-
-
-
-/// Computes offset eye poses based on headPose returned by ovrTrackingState.
-///
-/// \param[in] headPose Indicates the HMD position and orientation to use for the calculation.
-/// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
-/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
-/// of the two vectors for both eyes.
-/// \param[out] outEyePoses If outEyePoses are used for rendering, they should be passed to
-/// ovr_SubmitFrame in ovrLayerEyeFov::RenderPose or ovrLayerEyeFovDepth::RenderPose.
-///
-OVR_PUBLIC_FUNCTION(void) ovr_CalcEyePoses(ovrPosef headPose,
- const ovrVector3f hmdToEyeOffset[2],
- ovrPosef outEyePoses[2]);
-
-
-/// Returns the predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses.
-///
-/// This is a thread-safe function where caller should increment frameIndex with every frame
-/// and pass that index where applicable to functions called on the rendering thread.
-/// Assuming outEyePoses are used for rendering, it should be passed as a part of ovrLayerEyeFov.
-/// The caller does not need to worry about applying HmdToEyeOffset to the returned outEyePoses variables.
-///
-/// \param[in] hmd Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] frameIndex Specifies the targeted frame index, or 0 to refer to one frame after
-/// the last time ovr_SubmitFrame was called.
-/// \param[in] latencyMarker Specifies that this call is the point in time where
-/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer
-/// provides "SensorSampleTimestamp", that will override the value stored here.
-/// \param[in] hmdToEyeOffset Can be ovrEyeRenderDesc.HmdToEyeOffset returned from
-/// ovr_GetRenderDesc. For monoscopic rendering, use a vector that is the average
-/// of the two vectors for both eyes.
-/// \param[out] outEyePoses The predicted eye poses.
-/// \param[out] outSensorSampleTime The time when this function was called. May be NULL, in which case it is ignored.
-///
-OVR_PUBLIC_FUNCTION(void) ovr_GetEyePoses(ovrSession session, long long frameIndex, ovrBool latencyMarker,
- const ovrVector3f hmdToEyeOffset[2],
- ovrPosef outEyePoses[2],
- double* outSensorSampleTime);
-
-
-
-/// Tracking poses provided by the SDK come in a right-handed coordinate system. If an application
-/// is passing in ovrProjection_LeftHanded into ovrMatrix4f_Projection, then it should also use
-/// this function to flip the HMD tracking poses to be left-handed.
-///
-/// While this utility function is intended to convert a left-handed ovrPosef into a right-handed
-/// coordinate system, it will also work for converting right-handed to left-handed since the
-/// flip operation is the same for both cases.
-///
-/// \param[in] inPose that is right-handed
-/// \param[out] outPose that is requested to be left-handed (can be the same pointer to inPose)
-///
-OVR_PUBLIC_FUNCTION(void) ovrPosef_FlipHandedness(const ovrPosef* inPose, ovrPosef* outPose);
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-
-#endif // Header include guard
diff --git a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h
deleted file mode 100644
index 89293ff8..00000000
--- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_Math.h
+++ /dev/null
@@ -1,3804 +0,0 @@
-/********************************************************************************//**
-\file OVR_Math.h
-\brief Implementation of 3D primitives such as vectors, matrices.
-\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
-*************************************************************************************/
-
-#ifndef OVR_Math_h
-#define OVR_Math_h
-
-
-// This file is intended to be independent of the rest of LibOVR and LibOVRKernel and thus
-// has no #include dependencies on either.
-
-#include <math.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <float.h>
-#include "../OVR_CAPI.h" // Currently required due to a dependence on the ovrFovPort_ declaration.
-
-#if defined(_MSC_VER)
- #pragma warning(push)
- #pragma warning(disable: 4127) // conditional expression is constant
-#endif
-
-
-#if defined(_MSC_VER)
- #define OVRMath_sprintf sprintf_s
-#else
- #define OVRMath_sprintf snprintf
-#endif
-
-
-//-------------------------------------------------------------------------------------
-// ***** OVR_MATH_ASSERT
-//
-// Independent debug break implementation for OVR_Math.h.
-
-#if !defined(OVR_MATH_DEBUG_BREAK)
- #if defined(_DEBUG)
- #if defined(_MSC_VER)
- #define OVR_MATH_DEBUG_BREAK __debugbreak()
- #else
- #define OVR_MATH_DEBUG_BREAK __builtin_trap()
- #endif
- #else
- #define OVR_MATH_DEBUG_BREAK ((void)0)
- #endif
-#endif
-
-
-//-------------------------------------------------------------------------------------
-// ***** OVR_MATH_ASSERT
-//
-// Independent OVR_MATH_ASSERT implementation for OVR_Math.h.
-
-#if !defined(OVR_MATH_ASSERT)
- #if defined(_DEBUG)
- #define OVR_MATH_ASSERT(p) if (!(p)) { OVR_MATH_DEBUG_BREAK; }
- #else
- #define OVR_MATH_ASSERT(p) ((void)0)
- #endif
-#endif
-
-
-//-------------------------------------------------------------------------------------
-// ***** OVR_MATH_STATIC_ASSERT
-//
-// Independent OVR_MATH_ASSERT implementation for OVR_Math.h.
-
-#if !defined(OVR_MATH_STATIC_ASSERT)
- #if defined(__cplusplus) && ((defined(_MSC_VER) && (defined(_MSC_VER) >= 1600)) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L))
- #define OVR_MATH_STATIC_ASSERT static_assert
- #else
- #if !defined(OVR_SA_UNUSED)
- #if defined(__GNUC__) || defined(__clang__)
- #define OVR_SA_UNUSED __attribute__((unused))
- #else
- #define OVR_SA_UNUSED
- #endif
- #define OVR_SA_PASTE(a,b) a##b
- #define OVR_SA_HELP(a,b) OVR_SA_PASTE(a,b)
- #endif
-
- #define OVR_MATH_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED
- #endif
-#endif
-
-
-
-namespace OVR {
-
-template<class T>
-const T OVRMath_Min(const T a, const T b)
-{ return (a < b) ? a : b; }
-
-template<class T>
-const T OVRMath_Max(const T a, const T b)
-{ return (b < a) ? a : b; }
-
-template<class T>
-void OVRMath_Swap(T& a, T& b)
-{ T temp(a); a = b; b = temp; }
-
-
-//-------------------------------------------------------------------------------------
-// ***** Constants for 3D world/axis definitions.
-
-// Definitions of axes for coordinate and rotation conversions.
-enum Axis
-{
- Axis_X = 0, Axis_Y = 1, Axis_Z = 2
-};
-
-// RotateDirection describes the rotation direction around an axis, interpreted as follows:
-// CW - Clockwise while looking "down" from positive axis towards the origin.
-// CCW - Counter-clockwise while looking from the positive axis towards the origin,
-// which is in the negative axis direction.
-// CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate
-// system defines Y up, X right, and Z back (pointing out from the screen). In this
-// system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane.
-enum RotateDirection
-{
- Rotate_CCW = 1,
- Rotate_CW = -1
-};
-
-// Constants for right handed and left handed coordinate systems
-enum HandedSystem
-{
- Handed_R = 1, Handed_L = -1
-};
-
-// AxisDirection describes which way the coordinate axis points. Used by WorldAxes.
-enum AxisDirection
-{
- Axis_Up = 2,
- Axis_Down = -2,
- Axis_Right = 1,
- Axis_Left = -1,
- Axis_In = 3,
- Axis_Out = -3
-};
-
-struct WorldAxes
-{
- AxisDirection XAxis, YAxis, ZAxis;
-
- WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z)
- : XAxis(x), YAxis(y), ZAxis(z)
- { OVR_MATH_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));}
-};
-
-} // namespace OVR
-
-
-//------------------------------------------------------------------------------------//
-// ***** C Compatibility Types
-
-// These declarations are used to support conversion between C types used in
-// LibOVR C interfaces and their C++ versions. As an example, they allow passing
-// Vector3f into a function that expects ovrVector3f.
-
-typedef struct ovrQuatf_ ovrQuatf;
-typedef struct ovrQuatd_ ovrQuatd;
-typedef struct ovrSizei_ ovrSizei;
-typedef struct ovrSizef_ ovrSizef;
-typedef struct ovrSized_ ovrSized;
-typedef struct ovrRecti_ ovrRecti;
-typedef struct ovrVector2i_ ovrVector2i;
-typedef struct ovrVector2f_ ovrVector2f;
-typedef struct ovrVector2d_ ovrVector2d;
-typedef struct ovrVector3f_ ovrVector3f;
-typedef struct ovrVector3d_ ovrVector3d;
-typedef struct ovrVector4f_ ovrVector4f;
-typedef struct ovrVector4d_ ovrVector4d;
-typedef struct ovrMatrix2f_ ovrMatrix2f;
-typedef struct ovrMatrix2d_ ovrMatrix2d;
-typedef struct ovrMatrix3f_ ovrMatrix3f;
-typedef struct ovrMatrix3d_ ovrMatrix3d;
-typedef struct ovrMatrix4f_ ovrMatrix4f;
-typedef struct ovrMatrix4d_ ovrMatrix4d;
-typedef struct ovrPosef_ ovrPosef;
-typedef struct ovrPosed_ ovrPosed;
-typedef struct ovrPoseStatef_ ovrPoseStatef;
-typedef struct ovrPoseStated_ ovrPoseStated;
-
-namespace OVR {
-
-// Forward-declare our templates.
-template<class T> class Quat;
-template<class T> class Size;
-template<class T> class Rect;
-template<class T> class Vector2;
-template<class T> class Vector3;
-template<class T> class Vector4;
-template<class T> class Matrix2;
-template<class T> class Matrix3;
-template<class T> class Matrix4;
-template<class T> class Pose;
-template<class T> class PoseState;
-
-// CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class.
-template<class C>
-struct CompatibleTypes
-{
- // Declaration here seems necessary for MSVC; specializations are
- // used instead.
- typedef struct {} Type;
-};
-
-// Specializations providing CompatibleTypes::Type value.
-template<> struct CompatibleTypes<Quat<float> > { typedef ovrQuatf Type; };
-template<> struct CompatibleTypes<Quat<double> > { typedef ovrQuatd Type; };
-template<> struct CompatibleTypes<Matrix2<float> > { typedef ovrMatrix2f Type; };
-template<> struct CompatibleTypes<Matrix2<double> > { typedef ovrMatrix2d Type; };
-template<> struct CompatibleTypes<Matrix3<float> > { typedef ovrMatrix3f Type; };
-template<> struct CompatibleTypes<Matrix3<double> > { typedef ovrMatrix3d Type; };
-template<> struct CompatibleTypes<Matrix4<float> > { typedef ovrMatrix4f Type; };
-template<> struct CompatibleTypes<Matrix4<double> > { typedef ovrMatrix4d Type; };
-template<> struct CompatibleTypes<Size<int> > { typedef ovrSizei Type; };
-template<> struct CompatibleTypes<Size<float> > { typedef ovrSizef Type; };
-template<> struct CompatibleTypes<Size<double> > { typedef ovrSized Type; };
-template<> struct CompatibleTypes<Rect<int> > { typedef ovrRecti Type; };
-template<> struct CompatibleTypes<Vector2<int> > { typedef ovrVector2i Type; };
-template<> struct CompatibleTypes<Vector2<float> > { typedef ovrVector2f Type; };
-template<> struct CompatibleTypes<Vector2<double> > { typedef ovrVector2d Type; };
-template<> struct CompatibleTypes<Vector3<float> > { typedef ovrVector3f Type; };
-template<> struct CompatibleTypes<Vector3<double> > { typedef ovrVector3d Type; };
-template<> struct CompatibleTypes<Vector4<float> > { typedef ovrVector4f Type; };
-template<> struct CompatibleTypes<Vector4<double> > { typedef ovrVector4d Type; };
-template<> struct CompatibleTypes<Pose<float> > { typedef ovrPosef Type; };
-template<> struct CompatibleTypes<Pose<double> > { typedef ovrPosed Type; };
-
-//------------------------------------------------------------------------------------//
-// ***** Math
-//
-// Math class contains constants and functions. This class is a template specialized
-// per type, with Math<float> and Math<double> being distinct.
-template<class T>
-class Math
-{
-public:
- // By default, support explicit conversion to float. This allows Vector2<int> to
- // compile, for example.
- typedef float OtherFloatType;
-
- static int Tolerance() { return 0; } // Default value so integer types compile
-};
-
-
-//------------------------------------------------------------------------------------//
-// ***** double constants
-#define MATH_DOUBLE_PI 3.14159265358979323846
-#define MATH_DOUBLE_TWOPI (2*MATH_DOUBLE_PI)
-#define MATH_DOUBLE_PIOVER2 (0.5*MATH_DOUBLE_PI)
-#define MATH_DOUBLE_PIOVER4 (0.25*MATH_DOUBLE_PI)
-#define MATH_FLOAT_MAXVALUE (FLT_MAX)
-
-#define MATH_DOUBLE_RADTODEGREEFACTOR (360.0 / MATH_DOUBLE_TWOPI)
-#define MATH_DOUBLE_DEGREETORADFACTOR (MATH_DOUBLE_TWOPI / 360.0)
-
-#define MATH_DOUBLE_E 2.71828182845904523536
-#define MATH_DOUBLE_LOG2E 1.44269504088896340736
-#define MATH_DOUBLE_LOG10E 0.434294481903251827651
-#define MATH_DOUBLE_LN2 0.693147180559945309417
-#define MATH_DOUBLE_LN10 2.30258509299404568402
-
-#define MATH_DOUBLE_SQRT2 1.41421356237309504880
-#define MATH_DOUBLE_SQRT1_2 0.707106781186547524401
-
-#define MATH_DOUBLE_TOLERANCE 1e-12 // a default number for value equality tolerance: about 4500*Epsilon;
-#define MATH_DOUBLE_SINGULARITYRADIUS 1e-12 // about 1-cos(.0001 degree), for gimbal lock numerical problems
-
-//------------------------------------------------------------------------------------//
-// ***** float constants
-#define MATH_FLOAT_PI float(MATH_DOUBLE_PI)
-#define MATH_FLOAT_TWOPI float(MATH_DOUBLE_TWOPI)
-#define MATH_FLOAT_PIOVER2 float(MATH_DOUBLE_PIOVER2)
-#define MATH_FLOAT_PIOVER4 float(MATH_DOUBLE_PIOVER4)
-
-#define MATH_FLOAT_RADTODEGREEFACTOR float(MATH_DOUBLE_RADTODEGREEFACTOR)
-#define MATH_FLOAT_DEGREETORADFACTOR float(MATH_DOUBLE_DEGREETORADFACTOR)
-
-#define MATH_FLOAT_E float(MATH_DOUBLE_E)
-#define MATH_FLOAT_LOG2E float(MATH_DOUBLE_LOG2E)
-#define MATH_FLOAT_LOG10E float(MATH_DOUBLE_LOG10E)
-#define MATH_FLOAT_LN2 float(MATH_DOUBLE_LN2)
-#define MATH_FLOAT_LN10 float(MATH_DOUBLE_LN10)
-
-#define MATH_FLOAT_SQRT2 float(MATH_DOUBLE_SQRT2)
-#define MATH_FLOAT_SQRT1_2 float(MATH_DOUBLE_SQRT1_2)
-
-#define MATH_FLOAT_TOLERANCE 1e-5f // a default number for value equality tolerance: 1e-5, about 84*EPSILON;
-#define MATH_FLOAT_SINGULARITYRADIUS 1e-7f // about 1-cos(.025 degree), for gimbal lock numerical problems
-
-
-
-// Single-precision Math constants class.
-template<>
-class Math<float>
-{
-public:
- typedef double OtherFloatType;
-
- static inline float Tolerance() { return MATH_FLOAT_TOLERANCE; }; // a default number for value equality tolerance
- static inline float SingularityRadius() { return MATH_FLOAT_SINGULARITYRADIUS; }; // for gimbal lock numerical problems
-};
-
-// Double-precision Math constants class
-template<>
-class Math<double>
-{
-public:
- typedef float OtherFloatType;
-
- static inline double Tolerance() { return MATH_DOUBLE_TOLERANCE; }; // a default number for value equality tolerance
- static inline double SingularityRadius() { return MATH_DOUBLE_SINGULARITYRADIUS; }; // for gimbal lock numerical problems
-};
-
-typedef Math<float> Mathf;
-typedef Math<double> Mathd;
-
-// Conversion functions between degrees and radians
-// (non-templated to ensure passing int arguments causes warning)
-inline float RadToDegree(float rad) { return rad * MATH_FLOAT_RADTODEGREEFACTOR; }
-inline double RadToDegree(double rad) { return rad * MATH_DOUBLE_RADTODEGREEFACTOR; }
-
-inline float DegreeToRad(float deg) { return deg * MATH_FLOAT_DEGREETORADFACTOR; }
-inline double DegreeToRad(double deg) { return deg * MATH_DOUBLE_DEGREETORADFACTOR; }
-
-// Square function
-template<class T>
-inline T Sqr(T x) { return x*x; }
-
-// Sign: returns 0 if x == 0, -1 if x < 0, and 1 if x > 0
-template<class T>
-inline T Sign(T x) { return (x != T(0)) ? (x < T(0) ? T(-1) : T(1)) : T(0); }
-
-// Numerically stable acos function
-inline float Acos(float x) { return (x > 1.0f) ? 0.0f : (x < -1.0f) ? MATH_FLOAT_PI : acosf(x); }
-inline double Acos(double x) { return (x > 1.0) ? 0.0 : (x < -1.0) ? MATH_DOUBLE_PI : acos(x); }
-
-// Numerically stable asin function
-inline float Asin(float x) { return (x > 1.0f) ? MATH_FLOAT_PIOVER2 : (x < -1.0f) ? -MATH_FLOAT_PIOVER2 : asinf(x); }
-inline double Asin(double x) { return (x > 1.0) ? MATH_DOUBLE_PIOVER2 : (x < -1.0) ? -MATH_DOUBLE_PIOVER2 : asin(x); }
-
-#if defined(_MSC_VER)
- inline int isnan(double x) { return ::_isnan(x); }
-#elif !defined(isnan) // Some libraries #define isnan.
- inline int isnan(double x) { return ::isnan(x); }
-#endif
-
-template<class T>
-class Quat;
-
-
-//-------------------------------------------------------------------------------------
-// ***** Vector2<>
-
-// Vector2f (Vector2d) represents a 2-dimensional vector or point in space,
-// consisting of coordinates x and y
-
-template<class T>
-class Vector2
-{
-public:
- typedef T ElementType;
- static const size_t ElementCount = 2;
-
- T x, y;
-
- Vector2() : x(0), y(0) { }
- Vector2(T x_, T y_) : x(x_), y(y_) { }
- explicit Vector2(T s) : x(s), y(s) { }
- explicit Vector2(const Vector2<typename Math<T>::OtherFloatType> &src)
- : x((T)src.x), y((T)src.y) { }
-
- static Vector2 Zero() { return Vector2(0, 0); }
-
- // C-interop support.
- typedef typename CompatibleTypes<Vector2<T> >::Type CompatibleType;
-
- Vector2(const CompatibleType& s) : x(s.x), y(s.y) { }
-
- operator const CompatibleType& () const
- {
- OVR_MATH_STATIC_ASSERT(sizeof(Vector2<T>) == sizeof(CompatibleType), "sizeof(Vector2<T>) failure");
- return reinterpret_cast<const CompatibleType&>(*this);
- }
-
-
- bool operator== (const Vector2& b) const { return x == b.x && y == b.y; }
- bool operator!= (const Vector2& b) const { return x != b.x || y != b.y; }
-
- Vector2 operator+ (const Vector2& b) const { return Vector2(x + b.x, y + b.y); }
- Vector2& operator+= (const Vector2& b) { x += b.x; y += b.y; return *this; }
- Vector2 operator- (const Vector2& b) const { return Vector2(x - b.x, y - b.y); }
- Vector2& operator-= (const Vector2& b) { x -= b.x; y -= b.y; return *this; }
- Vector2 operator- () const { return Vector2(-x, -y); }
-
- // Scalar multiplication/division scales vector.
- Vector2 operator* (T s) const { return Vector2(x*s, y*s); }
- Vector2& operator*= (T s) { x *= s; y *= s; return *this; }
-
- Vector2 operator/ (T s) const { T rcp = T(1)/s;
- return Vector2(x*rcp, y*rcp); }
- Vector2& operator/= (T s) { T rcp = T(1)/s;
- x *= rcp; y *= rcp;
- return *this; }
-
- static Vector2 Min(const Vector2& a, const Vector2& b) { return Vector2((a.x < b.x) ? a.x : b.x,
- (a.y < b.y) ? a.y : b.y); }
- static Vector2 Max(const Vector2& a, const Vector2& b) { return Vector2((a.x > b.x) ? a.x : b.x,
- (a.y > b.y) ? a.y : b.y); }
-
- Vector2 Clamped(T maxMag) const
- {
- T magSquared = LengthSq();
- if (magSquared <= Sqr(maxMag))
- return *this;
- else
- return *this * (maxMag / sqrt(magSquared));
- }
-
- // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
- bool IsEqual(const Vector2& b, T tolerance =Math<T>::Tolerance()) const
- {
- return (fabs(b.x-x) <= tolerance) &&
- (fabs(b.y-y) <= tolerance);
- }
- bool Compare(const Vector2& b, T tolerance = Math<T>::Tolerance()) const
- {
- return IsEqual(b, tolerance);
- }
-
- // Access element by index
- T& operator[] (int idx)
- {
- OVR_MATH_ASSERT(0 <= idx && idx < 2);
- return *(&x + idx);
- }
- const T& operator[] (int idx) const
- {
- OVR_MATH_ASSERT(0 <= idx && idx < 2);
- return *(&x + idx);
- }
-
- // Entry-wise product of two vectors
- Vector2 EntrywiseMultiply(const Vector2& b) const { return Vector2(x * b.x, y * b.y);}
-
-
- // Multiply and divide operators do entry-wise math. Used Dot() for dot product.
- Vector2 operator* (const Vector2& b) const { return Vector2(x * b.x, y * b.y); }
- Vector2 operator/ (const Vector2& b) const { return Vector2(x / b.x, y / b.y); }
-
- // Dot product
- // Used to calculate angle q between two vectors among other things,
- // as (A dot B) = |a||b|cos(q).
- T Dot(const Vector2& b) const { return x*b.x + y*b.y; }
-
- // Returns the angle from this vector to b, in radians.
- T Angle(const Vector2& b) const
- {
- T div = LengthSq()*b.LengthSq();
- OVR_MATH_ASSERT(div != T(0));
- T result = Acos((this->Dot(b))/sqrt(div));
- return result;
- }
-
- // Return Length of the vector squared.
- T LengthSq() const { return (x * x + y * y); }
-
- // Return vector length.
- T Length() const { return sqrt(LengthSq()); }
-
- // Returns squared distance between two points represented by vectors.
- T DistanceSq(const Vector2& b) const { return (*this - b).LengthSq(); }
-
- // Returns distance between two points represented by vectors.
- T Distance(const Vector2& b) const { return (*this - b).Length(); }
-
- // Determine if this a unit vector.
- bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
-
- // Normalize, convention vector length to 1.
- void Normalize()
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- *this *= s;
- }
-
- // Returns normalized (unit) version of the vector without modifying itself.
- Vector2 Normalized() const
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- return *this * s;
- }
-
- // Linearly interpolates from this vector to another.
- // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
- Vector2 Lerp(const Vector2& b, T f) const { return *this*(T(1) - f) + b*f; }
-
- // Projects this vector onto the argument; in other words,
- // A.Project(B) returns projection of vector A onto B.
- Vector2 ProjectTo(const Vector2& b) const
- {
- T l2 = b.LengthSq();
- OVR_MATH_ASSERT(l2 != T(0));
- return b * ( Dot(b) / l2 );
- }
-
- // returns true if vector b is clockwise from this vector
- bool IsClockwise(const Vector2& b) const
- {
- return (x * b.y - y * b.x) < 0;
- }
-};
-
-
-typedef Vector2<float> Vector2f;
-typedef Vector2<double> Vector2d;
-typedef Vector2<int> Vector2i;
-
-typedef Vector2<float> Point2f;
-typedef Vector2<double> Point2d;
-typedef Vector2<int> Point2i;
-
-//-------------------------------------------------------------------------------------
-// ***** Vector3<> - 3D vector of {x, y, z}
-
-//
-// Vector3f (Vector3d) represents a 3-dimensional vector or point in space,
-// consisting of coordinates x, y and z.
-
-template<class T>
-class Vector3
-{
-public:
- typedef T ElementType;
- static const size_t ElementCount = 3;
-
- T x, y, z;
-
- // FIXME: default initialization of a vector class can be very expensive in a full-blown
- // application. A few hundred thousand vector constructions is not unlikely and can add
- // up to milliseconds of time on processors like the PS3 PPU.
- Vector3() : x(0), y(0), z(0) { }
- Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { }
- explicit Vector3(T s) : x(s), y(s), z(s) { }
- explicit Vector3(const Vector3<typename Math<T>::OtherFloatType> &src)
- : x((T)src.x), y((T)src.y), z((T)src.z) { }
-
- static Vector3 Zero() { return Vector3(0, 0, 0); }
-
- // C-interop support.
- typedef typename CompatibleTypes<Vector3<T> >::Type CompatibleType;
-
- Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) { }
-
- operator const CompatibleType& () const
- {
- OVR_MATH_STATIC_ASSERT(sizeof(Vector3<T>) == sizeof(CompatibleType), "sizeof(Vector3<T>) failure");
- return reinterpret_cast<const CompatibleType&>(*this);
- }
-
- bool operator== (const Vector3& b) const { return x == b.x && y == b.y && z == b.z; }
- bool operator!= (const Vector3& b) const { return x != b.x || y != b.y || z != b.z; }
-
- Vector3 operator+ (const Vector3& b) const { return Vector3(x + b.x, y + b.y, z + b.z); }
- Vector3& operator+= (const Vector3& b) { x += b.x; y += b.y; z += b.z; return *this; }
- Vector3 operator- (const Vector3& b) const { return Vector3(x - b.x, y - b.y, z - b.z); }
- Vector3& operator-= (const Vector3& b) { x -= b.x; y -= b.y; z -= b.z; return *this; }
- Vector3 operator- () const { return Vector3(-x, -y, -z); }
-
- // Scalar multiplication/division scales vector.
- Vector3 operator* (T s) const { return Vector3(x*s, y*s, z*s); }
- Vector3& operator*= (T s) { x *= s; y *= s; z *= s; return *this; }
-
- Vector3 operator/ (T s) const { T rcp = T(1)/s;
- return Vector3(x*rcp, y*rcp, z*rcp); }
- Vector3& operator/= (T s) { T rcp = T(1)/s;
- x *= rcp; y *= rcp; z *= rcp;
- return *this; }
-
- static Vector3 Min(const Vector3& a, const Vector3& b)
- {
- return Vector3((a.x < b.x) ? a.x : b.x,
- (a.y < b.y) ? a.y : b.y,
- (a.z < b.z) ? a.z : b.z);
- }
- static Vector3 Max(const Vector3& a, const Vector3& b)
- {
- return Vector3((a.x > b.x) ? a.x : b.x,
- (a.y > b.y) ? a.y : b.y,
- (a.z > b.z) ? a.z : b.z);
- }
-
- Vector3 Clamped(T maxMag) const
- {
- T magSquared = LengthSq();
- if (magSquared <= Sqr(maxMag))
- return *this;
- else
- return *this * (maxMag / sqrt(magSquared));
- }
-
- // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
- bool IsEqual(const Vector3& b, T tolerance = Math<T>::Tolerance()) const
- {
- return (fabs(b.x-x) <= tolerance) &&
- (fabs(b.y-y) <= tolerance) &&
- (fabs(b.z-z) <= tolerance);
- }
- bool Compare(const Vector3& b, T tolerance = Math<T>::Tolerance()) const
- {
- return IsEqual(b, tolerance);
- }
-
- T& operator[] (int idx)
- {
- OVR_MATH_ASSERT(0 <= idx && idx < 3);
- return *(&x + idx);
- }
-
- const T& operator[] (int idx) const
- {
- OVR_MATH_ASSERT(0 <= idx && idx < 3);
- return *(&x + idx);
- }
-
- // Entrywise product of two vectors
- Vector3 EntrywiseMultiply(const Vector3& b) const { return Vector3(x * b.x,
- y * b.y,
- z * b.z);}
-
- // Multiply and divide operators do entry-wise math
- Vector3 operator* (const Vector3& b) const { return Vector3(x * b.x,
- y * b.y,
- z * b.z); }
-
- Vector3 operator/ (const Vector3& b) const { return Vector3(x / b.x,
- y / b.y,
- z / b.z); }
-
-
- // Dot product
- // Used to calculate angle q between two vectors among other things,
- // as (A dot B) = |a||b|cos(q).
- T Dot(const Vector3& b) const { return x*b.x + y*b.y + z*b.z; }
-
- // Compute cross product, which generates a normal vector.
- // Direction vector can be determined by right-hand rule: Pointing index finder in
- // direction a and middle finger in direction b, thumb will point in a.Cross(b).
- Vector3 Cross(const Vector3& b) const { return Vector3(y*b.z - z*b.y,
- z*b.x - x*b.z,
- x*b.y - y*b.x); }
-
- // Returns the angle from this vector to b, in radians.
- T Angle(const Vector3& b) const
- {
- T div = LengthSq()*b.LengthSq();
- OVR_MATH_ASSERT(div != T(0));
- T result = Acos((this->Dot(b))/sqrt(div));
- return result;
- }
-
- // Return Length of the vector squared.
- T LengthSq() const { return (x * x + y * y + z * z); }
-
- // Return vector length.
- T Length() const { return (T)sqrt(LengthSq()); }
-
- // Returns squared distance between two points represented by vectors.
- T DistanceSq(Vector3 const& b) const { return (*this - b).LengthSq(); }
-
- // Returns distance between two points represented by vectors.
- T Distance(Vector3 const& b) const { return (*this - b).Length(); }
-
- bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
-
- // Normalize, convention vector length to 1.
- void Normalize()
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- *this *= s;
- }
-
- // Returns normalized (unit) version of the vector without modifying itself.
- Vector3 Normalized() const
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- return *this * s;
- }
-
- // Linearly interpolates from this vector to another.
- // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
- Vector3 Lerp(const Vector3& b, T f) const { return *this*(T(1) - f) + b*f; }
-
- // Projects this vector onto the argument; in other words,
- // A.Project(B) returns projection of vector A onto B.
- Vector3 ProjectTo(const Vector3& b) const
- {
- T l2 = b.LengthSq();
- OVR_MATH_ASSERT(l2 != T(0));
- return b * ( Dot(b) / l2 );
- }
-
- // Projects this vector onto a plane defined by a normal vector
- Vector3 ProjectToPlane(const Vector3& normal) const { return *this - this->ProjectTo(normal); }
-};
-
-typedef Vector3<float> Vector3f;
-typedef Vector3<double> Vector3d;
-typedef Vector3<int32_t> Vector3i;
-
-OVR_MATH_STATIC_ASSERT((sizeof(Vector3f) == 3*sizeof(float)), "sizeof(Vector3f) failure");
-OVR_MATH_STATIC_ASSERT((sizeof(Vector3d) == 3*sizeof(double)), "sizeof(Vector3d) failure");
-OVR_MATH_STATIC_ASSERT((sizeof(Vector3i) == 3*sizeof(int32_t)), "sizeof(Vector3i) failure");
-
-typedef Vector3<float> Point3f;
-typedef Vector3<double> Point3d;
-typedef Vector3<int32_t> Point3i;
-
-
-//-------------------------------------------------------------------------------------
-// ***** Vector4<> - 4D vector of {x, y, z, w}
-
-//
-// Vector4f (Vector4d) represents a 3-dimensional vector or point in space,
-// consisting of coordinates x, y, z and w.
-
-template<class T>
-class Vector4
-{
-public:
- typedef T ElementType;
- static const size_t ElementCount = 4;
-
- T x, y, z, w;
-
- // FIXME: default initialization of a vector class can be very expensive in a full-blown
- // application. A few hundred thousand vector constructions is not unlikely and can add
- // up to milliseconds of time on processors like the PS3 PPU.
- Vector4() : x(0), y(0), z(0), w(0) { }
- Vector4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { }
- explicit Vector4(T s) : x(s), y(s), z(s), w(s) { }
- explicit Vector4(const Vector3<T>& v, const T w_=T(1)) : x(v.x), y(v.y), z(v.z), w(w_) { }
- explicit Vector4(const Vector4<typename Math<T>::OtherFloatType> &src)
- : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { }
-
- static Vector4 Zero() { return Vector4(0, 0, 0, 0); }
-
- // C-interop support.
- typedef typename CompatibleTypes< Vector4<T> >::Type CompatibleType;
-
- Vector4(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { }
-
- operator const CompatibleType& () const
- {
- OVR_MATH_STATIC_ASSERT(sizeof(Vector4<T>) == sizeof(CompatibleType), "sizeof(Vector4<T>) failure");
- return reinterpret_cast<const CompatibleType&>(*this);
- }
-
- Vector4& operator= (const Vector3<T>& other) { x=other.x; y=other.y; z=other.z; w=1; return *this; }
- bool operator== (const Vector4& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; }
- bool operator!= (const Vector4& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; }
-
- Vector4 operator+ (const Vector4& b) const { return Vector4(x + b.x, y + b.y, z + b.z, w + b.w); }
- Vector4& operator+= (const Vector4& b) { x += b.x; y += b.y; z += b.z; w += b.w; return *this; }
- Vector4 operator- (const Vector4& b) const { return Vector4(x - b.x, y - b.y, z - b.z, w - b.w); }
- Vector4& operator-= (const Vector4& b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; return *this; }
- Vector4 operator- () const { return Vector4(-x, -y, -z, -w); }
-
- // Scalar multiplication/division scales vector.
- Vector4 operator* (T s) const { return Vector4(x*s, y*s, z*s, w*s); }
- Vector4& operator*= (T s) { x *= s; y *= s; z *= s; w *= s;return *this; }
-
- Vector4 operator/ (T s) const { T rcp = T(1)/s;
- return Vector4(x*rcp, y*rcp, z*rcp, w*rcp); }
- Vector4& operator/= (T s) { T rcp = T(1)/s;
- x *= rcp; y *= rcp; z *= rcp; w *= rcp;
- return *this; }
-
- static Vector4 Min(const Vector4& a, const Vector4& b)
- {
- return Vector4((a.x < b.x) ? a.x : b.x,
- (a.y < b.y) ? a.y : b.y,
- (a.z < b.z) ? a.z : b.z,
- (a.w < b.w) ? a.w : b.w);
- }
- static Vector4 Max(const Vector4& a, const Vector4& b)
- {
- return Vector4((a.x > b.x) ? a.x : b.x,
- (a.y > b.y) ? a.y : b.y,
- (a.z > b.z) ? a.z : b.z,
- (a.w > b.w) ? a.w : b.w);
- }
-
- Vector4 Clamped(T maxMag) const
- {
- T magSquared = LengthSq();
- if (magSquared <= Sqr(maxMag))
- return *this;
- else
- return *this * (maxMag / sqrt(magSquared));
- }
-
- // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance.
- bool IsEqual(const Vector4& b, T tolerance = Math<T>::Tolerance()) const
- {
- return (fabs(b.x-x) <= tolerance) &&
- (fabs(b.y-y) <= tolerance) &&
- (fabs(b.z-z) <= tolerance) &&
- (fabs(b.w-w) <= tolerance);
- }
- bool Compare(const Vector4& b, T tolerance = Math<T>::Tolerance()) const
- {
- return IsEqual(b, tolerance);
- }
-
- T& operator[] (int idx)
- {
- OVR_MATH_ASSERT(0 <= idx && idx < 4);
- return *(&x + idx);
- }
-
- const T& operator[] (int idx) const
- {
- OVR_MATH_ASSERT(0 <= idx && idx < 4);
- return *(&x + idx);
- }
-
- // Entry wise product of two vectors
- Vector4 EntrywiseMultiply(const Vector4& b) const { return Vector4(x * b.x,
- y * b.y,
- z * b.z,
- w * b.w);}
-
- // Multiply and divide operators do entry-wise math
- Vector4 operator* (const Vector4& b) const { return Vector4(x * b.x,
- y * b.y,
- z * b.z,
- w * b.w); }
-
- Vector4 operator/ (const Vector4& b) const { return Vector4(x / b.x,
- y / b.y,
- z / b.z,
- w / b.w); }
-
-
- // Dot product
- T Dot(const Vector4& b) const { return x*b.x + y*b.y + z*b.z + w*b.w; }
-
- // Return Length of the vector squared.
- T LengthSq() const { return (x * x + y * y + z * z + w * w); }
-
- // Return vector length.
- T Length() const { return sqrt(LengthSq()); }
-
- bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
-
- // Normalize, convention vector length to 1.
- void Normalize()
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- *this *= s;
- }
-
- // Returns normalized (unit) version of the vector without modifying itself.
- Vector4 Normalized() const
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- return *this * s;
- }
-
- // Linearly interpolates from this vector to another.
- // Factor should be between 0.0 and 1.0, with 0 giving full value to this.
- Vector4 Lerp(const Vector4& b, T f) const { return *this*(T(1) - f) + b*f; }
-};
-
-typedef Vector4<float> Vector4f;
-typedef Vector4<double> Vector4d;
-typedef Vector4<int> Vector4i;
-
-
-//-------------------------------------------------------------------------------------
-// ***** Bounds3
-
-// Bounds class used to describe a 3D axis aligned bounding box.
-
-template<class T>
-class Bounds3
-{
-public:
- Vector3<T> b[2];
-
- Bounds3()
- {
- }
-
- Bounds3( const Vector3<T> & mins, const Vector3<T> & maxs )
-{
- b[0] = mins;
- b[1] = maxs;
- }
-
- void Clear()
- {
- b[0].x = b[0].y = b[0].z = Math<T>::MaxValue;
- b[1].x = b[1].y = b[1].z = -Math<T>::MaxValue;
- }
-
- void AddPoint( const Vector3<T> & v )
- {
- b[0].x = (b[0].x < v.x ? b[0].x : v.x);
- b[0].y = (b[0].y < v.y ? b[0].y : v.y);
- b[0].z = (b[0].z < v.z ? b[0].z : v.z);
- b[1].x = (v.x < b[1].x ? b[1].x : v.x);
- b[1].y = (v.y < b[1].y ? b[1].y : v.y);
- b[1].z = (v.z < b[1].z ? b[1].z : v.z);
- }
-
- const Vector3<T> & GetMins() const { return b[0]; }
- const Vector3<T> & GetMaxs() const { return b[1]; }
-
- Vector3<T> & GetMins() { return b[0]; }
- Vector3<T> & GetMaxs() { return b[1]; }
-};
-
-typedef Bounds3<float> Bounds3f;
-typedef Bounds3<double> Bounds3d;
-
-
-//-------------------------------------------------------------------------------------
-// ***** Size
-
-// Size class represents 2D size with Width, Height components.
-// Used to describe distentions of render targets, etc.
-
-template<class T>
-class Size
-{
-public:
- T w, h;
-
- Size() : w(0), h(0) { }
- Size(T w_, T h_) : w(w_), h(h_) { }
- explicit Size(T s) : w(s), h(s) { }
- explicit Size(const Size<typename Math<T>::OtherFloatType> &src)
- : w((T)src.w), h((T)src.h) { }
-
- // C-interop support.
- typedef typename CompatibleTypes<Size<T> >::Type CompatibleType;
-
- Size(const CompatibleType& s) : w(s.w), h(s.h) { }
-
- operator const CompatibleType& () const
- {
- OVR_MATH_STATIC_ASSERT(sizeof(Size<T>) == sizeof(CompatibleType), "sizeof(Size<T>) failure");
- return reinterpret_cast<const CompatibleType&>(*this);
- }
-
- bool operator== (const Size& b) const { return w == b.w && h == b.h; }
- bool operator!= (const Size& b) const { return w != b.w || h != b.h; }
-
- Size operator+ (const Size& b) const { return Size(w + b.w, h + b.h); }
- Size& operator+= (const Size& b) { w += b.w; h += b.h; return *this; }
- Size operator- (const Size& b) const { return Size(w - b.w, h - b.h); }
- Size& operator-= (const Size& b) { w -= b.w; h -= b.h; return *this; }
- Size operator- () const { return Size(-w, -h); }
- Size operator* (const Size& b) const { return Size(w * b.w, h * b.h); }
- Size& operator*= (const Size& b) { w *= b.w; h *= b.h; return *this; }
- Size operator/ (const Size& b) const { return Size(w / b.w, h / b.h); }
- Size& operator/= (const Size& b) { w /= b.w; h /= b.h; return *this; }
-
- // Scalar multiplication/division scales both components.
- Size operator* (T s) const { return Size(w*s, h*s); }
- Size& operator*= (T s) { w *= s; h *= s; return *this; }
- Size operator/ (T s) const { return Size(w/s, h/s); }
- Size& operator/= (T s) { w /= s; h /= s; return *this; }
-
- static Size Min(const Size& a, const Size& b) { return Size((a.w < b.w) ? a.w : b.w,
- (a.h < b.h) ? a.h : b.h); }
- static Size Max(const Size& a, const Size& b) { return Size((a.w > b.w) ? a.w : b.w,
- (a.h > b.h) ? a.h : b.h); }
-
- T Area() const { return w * h; }
-
- inline Vector2<T> ToVector() const { return Vector2<T>(w, h); }
-};
-
-
-typedef Size<int> Sizei;
-typedef Size<unsigned> Sizeu;
-typedef Size<float> Sizef;
-typedef Size<double> Sized;
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** Rect
-
-// Rect describes a rectangular area for rendering, that includes position and size.
-template<class T>
-class Rect
-{
-public:
- T x, y;
- T w, h;
-
- Rect() { }
- Rect(T x1, T y1, T w1, T h1) : x(x1), y(y1), w(w1), h(h1) { }
- Rect(const Vector2<T>& pos, const Size<T>& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) { }
- Rect(const Size<T>& sz) : x(0), y(0), w(sz.w), h(sz.h) { }
-
- // C-interop support.
- typedef typename CompatibleTypes<Rect<T> >::Type CompatibleType;
-
- Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) { }
-
- operator const CompatibleType& () const
- {
- OVR_MATH_STATIC_ASSERT(sizeof(Rect<T>) == sizeof(CompatibleType), "sizeof(Rect<T>) failure");
- return reinterpret_cast<const CompatibleType&>(*this);
- }
-
- Vector2<T> GetPos() const { return Vector2<T>(x, y); }
- Size<T> GetSize() const { return Size<T>(w, h); }
- void SetPos(const Vector2<T>& pos) { x = pos.x; y = pos.y; }
- void SetSize(const Size<T>& sz) { w = sz.w; h = sz.h; }
-
- bool operator == (const Rect& vp) const
- { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); }
- bool operator != (const Rect& vp) const
- { return !operator == (vp); }
-};
-
-typedef Rect<int> Recti;
-
-
-//-------------------------------------------------------------------------------------//
-// ***** Quat
-//
-// Quatf represents a quaternion class used for rotations.
-//
-// Quaternion multiplications are done in right-to-left order, to match the
-// behavior of matrices.
-
-
-template<class T>
-class Quat
-{
-public:
- typedef T ElementType;
- static const size_t ElementCount = 4;
-
- // x,y,z = axis*sin(angle), w = cos(angle)
- T x, y, z, w;
-
- Quat() : x(0), y(0), z(0), w(1) { }
- Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { }
- explicit Quat(const Quat<typename Math<T>::OtherFloatType> &src)
- : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w)
- {
- // NOTE: Converting a normalized Quat<float> to Quat<double>
- // will generally result in an un-normalized quaternion.
- // But we don't normalize here in case the quaternion
- // being converted is not a normalized rotation quaternion.
- }
-
- typedef typename CompatibleTypes<Quat<T> >::Type CompatibleType;
-
- // C-interop support.
- Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { }
-
- operator CompatibleType () const
- {
- CompatibleType result;
- result.x = x;
- result.y = y;
- result.z = z;
- result.w = w;
- return result;
- }
-
- // Constructs quaternion for rotation around the axis by an angle.
- Quat(const Vector3<T>& axis, T angle)
- {
- // Make sure we don't divide by zero.
- if (axis.LengthSq() == T(0))
- {
- // Assert if the axis is zero, but the angle isn't
- OVR_MATH_ASSERT(angle == T(0));
- x = y = z = T(0); w = T(1);
- return;
- }
-
- Vector3<T> unitAxis = axis.Normalized();
- T sinHalfAngle = sin(angle * T(0.5));
-
- w = cos(angle * T(0.5));
- x = unitAxis.x * sinHalfAngle;
- y = unitAxis.y * sinHalfAngle;
- z = unitAxis.z * sinHalfAngle;
- }
-
- // Constructs quaternion for rotation around one of the coordinate axis by an angle.
- Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R)
- {
- T sinHalfAngle = s * d *sin(angle * T(0.5));
- T v[3];
- v[0] = v[1] = v[2] = T(0);
- v[A] = sinHalfAngle;
-
- w = cos(angle * T(0.5));
- x = v[0];
- y = v[1];
- z = v[2];
- }
-
- Quat operator-() { return Quat(-x, -y, -z, -w); } // unary minus
-
- static Quat Identity() { return Quat(0, 0, 0, 1); }
-
- // Compute axis and angle from quaternion
- void GetAxisAngle(Vector3<T>* axis, T* angle) const
- {
- if ( x*x + y*y + z*z > Math<T>::Tolerance() * Math<T>::Tolerance() ) {
- *axis = Vector3<T>(x, y, z).Normalized();
- *angle = 2 * Acos(w);
- if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary
- {
- *angle = ((T)MATH_DOUBLE_TWOPI) - *angle;
- *axis = *axis * (-1);
- }
- }
- else
- {
- *axis = Vector3<T>(1, 0, 0);
- *angle= T(0);
- }
- }
-
- // Convert a quaternion to a rotation vector, also known as
- // Rodrigues vector, AxisAngle vector, SORA vector, exponential map.
- // A rotation vector describes a rotation about an axis:
- // the axis of rotation is the vector normalized,
- // the angle of rotation is the magnitude of the vector.
- Vector3<T> ToRotationVector() const
- {
- OVR_MATH_ASSERT(IsNormalized() || LengthSq() == 0);
- T s = T(0);
- T sinHalfAngle = sqrt(x*x + y*y + z*z);
- if (sinHalfAngle > T(0))
- {
- T cosHalfAngle = w;
- T halfAngle = atan2(sinHalfAngle, cosHalfAngle);
-
- // Ensure minimum rotation magnitude
- if (cosHalfAngle < 0)
- halfAngle -= T(MATH_DOUBLE_PI);
-
- s = T(2) * halfAngle / sinHalfAngle;
- }
- return Vector3<T>(x*s, y*s, z*s);
- }
-
- // Faster version of the above, optimized for use with small rotations, where rotation angle ~= sin(angle)
- inline OVR::Vector3<T> FastToRotationVector() const
- {
- OVR_MATH_ASSERT(IsNormalized());
- T s;
- T sinHalfSquared = x*x + y*y + z*z;
- if (sinHalfSquared < T(.0037)) // =~ sin(7/2 degrees)^2
- {
- // Max rotation magnitude error is about .062% at 7 degrees rotation, or about .0043 degrees
- s = T(2) * Sign(w);
- }
- else
- {
- T sinHalfAngle = sqrt(sinHalfSquared);
- T cosHalfAngle = w;
- T halfAngle = atan2(sinHalfAngle, cosHalfAngle);
-
- // Ensure minimum rotation magnitude
- if (cosHalfAngle < 0)
- halfAngle -= T(MATH_DOUBLE_PI);
-
- s = T(2) * halfAngle / sinHalfAngle;
- }
- return Vector3<T>(x*s, y*s, z*s);
- }
-
- // Given a rotation vector of form unitRotationAxis * angle,
- // returns the equivalent quaternion (unitRotationAxis * sin(angle), cos(Angle)).
- static Quat FromRotationVector(const Vector3<T>& v)
- {
- T angleSquared = v.LengthSq();
- T s = T(0);
- T c = T(1);
- if (angleSquared > T(0))
- {
- T angle = sqrt(angleSquared);
- s = sin(angle * T(0.5)) / angle; // normalize
- c = cos(angle * T(0.5));
- }
- return Quat(s*v.x, s*v.y, s*v.z, c);
- }
-
- // Faster version of above, optimized for use with small rotation magnitudes, where rotation angle =~ sin(angle).
- // If normalize is false, small-angle quaternions are returned un-normalized.
- inline static Quat FastFromRotationVector(const OVR::Vector3<T>& v, bool normalize = true)
- {
- T s, c;
- T angleSquared = v.LengthSq();
- if (angleSquared < T(0.0076)) // =~ (5 degrees*pi/180)^2
- {
- s = T(0.5);
- c = T(1.0);
- // Max rotation magnitude error (after normalization) is about .064% at 5 degrees rotation, or .0032 degrees
- if (normalize && angleSquared > 0)
- {
- // sin(angle/2)^2 ~= (angle/2)^2 and cos(angle/2)^2 ~= 1
- T invLen = T(1) / sqrt(angleSquared * T(0.25) + T(1)); // normalize
- s = s * invLen;
- c = c * invLen;
- }
- }
- else
- {
- T angle = sqrt(angleSquared);
- s = sin(angle * T(0.5)) / angle;
- c = cos(angle * T(0.5));
- }
- return Quat(s*v.x, s*v.y, s*v.z, c);
- }
-
- // Constructs the quaternion from a rotation matrix
- explicit Quat(const Matrix4<T>& m)
- {
- T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
-
- // In almost all cases, the first part is executed.
- // However, if the trace is not positive, the other
- // cases arise.
- if (trace > T(0))
- {
- T s = sqrt(trace + T(1)) * T(2); // s=4*qw
- w = T(0.25) * s;
- x = (m.M[2][1] - m.M[1][2]) / s;
- y = (m.M[0][2] - m.M[2][0]) / s;
- z = (m.M[1][0] - m.M[0][1]) / s;
- }
- else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
- {
- T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
- w = (m.M[2][1] - m.M[1][2]) / s;
- x = T(0.25) * s;
- y = (m.M[0][1] + m.M[1][0]) / s;
- z = (m.M[2][0] + m.M[0][2]) / s;
- }
- else if (m.M[1][1] > m.M[2][2])
- {
- T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
- w = (m.M[0][2] - m.M[2][0]) / s;
- x = (m.M[0][1] + m.M[1][0]) / s;
- y = T(0.25) * s;
- z = (m.M[1][2] + m.M[2][1]) / s;
- }
- else
- {
- T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
- w = (m.M[1][0] - m.M[0][1]) / s;
- x = (m.M[0][2] + m.M[2][0]) / s;
- y = (m.M[1][2] + m.M[2][1]) / s;
- z = T(0.25) * s;
- }
- OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal
- }
-
- // Constructs the quaternion from a rotation matrix
- explicit Quat(const Matrix3<T>& m)
- {
- T trace = m.M[0][0] + m.M[1][1] + m.M[2][2];
-
- // In almost all cases, the first part is executed.
- // However, if the trace is not positive, the other
- // cases arise.
- if (trace > T(0))
- {
- T s = sqrt(trace + T(1)) * T(2); // s=4*qw
- w = T(0.25) * s;
- x = (m.M[2][1] - m.M[1][2]) / s;
- y = (m.M[0][2] - m.M[2][0]) / s;
- z = (m.M[1][0] - m.M[0][1]) / s;
- }
- else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2]))
- {
- T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2);
- w = (m.M[2][1] - m.M[1][2]) / s;
- x = T(0.25) * s;
- y = (m.M[0][1] + m.M[1][0]) / s;
- z = (m.M[2][0] + m.M[0][2]) / s;
- }
- else if (m.M[1][1] > m.M[2][2])
- {
- T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy
- w = (m.M[0][2] - m.M[2][0]) / s;
- x = (m.M[0][1] + m.M[1][0]) / s;
- y = T(0.25) * s;
- z = (m.M[1][2] + m.M[2][1]) / s;
- }
- else
- {
- T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz
- w = (m.M[1][0] - m.M[0][1]) / s;
- x = (m.M[0][2] + m.M[2][0]) / s;
- y = (m.M[1][2] + m.M[2][1]) / s;
- z = T(0.25) * s;
- }
- OVR_MATH_ASSERT(IsNormalized()); // Ensure input matrix is orthogonal
- }
-
- bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; }
- bool operator!= (const Quat& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; }
-
- Quat operator+ (const Quat& b) const { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); }
- Quat& operator+= (const Quat& b) { w += b.w; x += b.x; y += b.y; z += b.z; return *this; }
- Quat operator- (const Quat& b) const { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); }
- Quat& operator-= (const Quat& b) { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; }
-
- Quat operator* (T s) const { return Quat(x * s, y * s, z * s, w * s); }
- Quat& operator*= (T s) { w *= s; x *= s; y *= s; z *= s; return *this; }
- Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); }
- Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; }
-
- // Compare two quats for equality within tolerance. Returns true if quats match withing tolerance.
- bool IsEqual(const Quat& b, T tolerance = Math<T>::Tolerance()) const
- {
- return Abs(Dot(b)) >= T(1) - tolerance;
- }
-
- static T Abs(const T v) { return (v >= 0) ? v : -v; }
-
- // Get Imaginary part vector
- Vector3<T> Imag() const { return Vector3<T>(x,y,z); }
-
- // Get quaternion length.
- T Length() const { return sqrt(LengthSq()); }
-
- // Get quaternion length squared.
- T LengthSq() const { return (x * x + y * y + z * z + w * w); }
-
- // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure)
- T Distance(const Quat& q) const
- {
- T d1 = (*this - q).Length();
- T d2 = (*this + q).Length(); // Antipodal point check
- return (d1 < d2) ? d1 : d2;
- }
-
- T DistanceSq(const Quat& q) const
- {
- T d1 = (*this - q).LengthSq();
- T d2 = (*this + q).LengthSq(); // Antipodal point check
- return (d1 < d2) ? d1 : d2;
- }
-
- T Dot(const Quat& q) const
- {
- return x * q.x + y * q.y + z * q.z + w * q.w;
- }
-
- // Angle between two quaternions in radians
- T Angle(const Quat& q) const
- {
- return T(2) * Acos(Abs(Dot(q)));
- }
-
- // Angle of quaternion
- T Angle() const
- {
- return T(2) * Acos(Abs(w));
- }
-
- // Normalize
- bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math<T>::Tolerance(); }
-
- void Normalize()
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- *this *= s;
- }
-
- Quat Normalized() const
- {
- T s = Length();
- if (s != T(0))
- s = T(1) / s;
- return *this * s;
- }
-
- inline void EnsureSameHemisphere(const Quat& o)
- {
- if (Dot(o) < T(0))
- {
- x = -x;
- y = -y;
- z = -z;
- w = -w;
- }
- }
-
- // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized.
- Quat Conj() const { return Quat(-x, -y, -z, w); }
-
- // Quaternion multiplication. Combines quaternion rotations, performing the one on the
- // right hand side first.
- Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y,
- w * b.y - x * b.z + y * b.w + z * b.x,
- w * b.z + x * b.y - y * b.x + z * b.w,
- w * b.w - x * b.x - y * b.y - z * b.z); }
- const Quat& operator*= (const Quat& b) { *this = *this * b; return *this; }
-
- //
- // this^p normalized; same as rotating by this p times.
- Quat PowNormalized(T p) const
- {
- Vector3<T> v;
- T a;
- GetAxisAngle(&v, &a);
- return Quat(v, a * p);
- }
-
- // Compute quaternion that rotates v into alignTo: alignTo = Quat::Align(alignTo, v).Rotate(v).
- // NOTE: alignTo and v must be normalized.
- static Quat Align(const Vector3<T>& alignTo, const Vector3<T>& v)
- {
- OVR_MATH_ASSERT(alignTo.IsNormalized() && v.IsNormalized());
- Vector3<T> bisector = (v + alignTo);
- bisector.Normalize();
- T cosHalfAngle = v.Dot(bisector); // 0..1
- if (cosHalfAngle > T(0))
- {
- Vector3<T> imag = v.Cross(bisector);
- return Quat(imag.x, imag.y, imag.z, cosHalfAngle);
- }
- else
- {
- // cosHalfAngle == 0: a 180 degree rotation.
- // sinHalfAngle == 1, rotation axis is any axis perpendicular
- // to alignTo. Choose axis to include largest magnitude components
- if (fabs(v.x) > fabs(v.y))
- {
- // x or z is max magnitude component
- // = Cross(v, (0,1,0)).Normalized();
- T invLen = sqrt(v.x*v.x + v.z*v.z);
- if (invLen > T(0))
- invLen = T(1) / invLen;
- return Quat(-v.z*invLen, 0, v.x*invLen, 0);
- }
- else
- {
- // y or z is max magnitude component
- // = Cross(v, (1,0,0)).Normalized();
- T invLen = sqrt(v.y*v.y + v.z*v.z);
- if (invLen > T(0))
- invLen = T(1) / invLen;
- return Quat(0, v.z*invLen, -v.y*invLen, 0);
- }
- }
- }
-
- // Decompose a quat into quat = swing * twist, where twist is a rotation about axis,
- // and swing is a rotation perpendicular to axis.
- Quat GetSwingTwist(const Vector3<T>& axis, Quat* twist) const
- {
- OVR_MATH_ASSERT(twist);
- OVR_MATH_ASSERT(axis.IsNormalized());
-
- // Create a normalized quaternion from projection of (x,y,z) onto axis
- T d = axis.Dot(Vector3<T>(x, y, z));
- *twist = Quat(axis.x*d, axis.y*d, axis.z*d, w);
- T len = twist->Length();
- if (len == 0)
- twist->w = T(1); // identity
- else
- *twist /= len; // normalize
-
- return *this * twist->Inverted();
- }
-
- // Normalized linear interpolation of quaternions
- // NOTE: This function is a bad approximation of Slerp()
- // when the angle between the *this and b is large.
- // Use FastSlerp() or Slerp() instead.
- Quat Lerp(const Quat& b, T s) const
- {
- return (*this * (T(1) - s) + b * (Dot(b) < 0 ? -s : s)).Normalized();
- }
-
- // Spherical linear interpolation between rotations
- Quat Slerp(const Quat& b, T s) const
- {
- Vector3<T> delta = (b * this->Inverted()).ToRotationVector();
- return (FromRotationVector(delta * s) * *this).Normalized(); // normalize so errors don't accumulate
- }
-
- // Spherical linear interpolation: much faster for small rotations, accurate for large rotations. See FastTo/FromRotationVector
- Quat FastSlerp(const Quat& b, T s) const
- {
- Vector3<T> delta = (b * this->Inverted()).FastToRotationVector();
- return (FastFromRotationVector(delta * s, false) * *this).Normalized();
- }
-
- // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise,
- // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1.
- Vector3<T> Rotate(const Vector3<T>& v) const
- {
- OVR_MATH_ASSERT(isnan(w) || IsNormalized());
-
- // rv = q * (v,0) * q'
- // Same as rv = v + real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2);
-
- // uv = 2 * Imag().Cross(v);
- T uvx = T(2) * (y*v.z - z*v.y);
- T uvy = T(2) * (z*v.x - x*v.z);
- T uvz = T(2) * (x*v.y - y*v.x);
-
- // return v + Real()*uv + Imag().Cross(uv);
- return Vector3<T>(v.x + w*uvx + y*uvz - z*uvy,
- v.y + w*uvy + z*uvx - x*uvz,
- v.z + w*uvz + x*uvy - y*uvx);
- }
-
- // Rotation by inverse of *this
- Vector3<T> InverseRotate(const Vector3<T>& v) const
- {
- OVR_MATH_ASSERT(IsNormalized());
-
- // rv = q' * (v,0) * q
- // Same as rv = v + real * cross(-imag,v)*2 + cross(-imag, cross(-imag,v)*2);
- // or rv = v - real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2);
-
- // uv = 2 * Imag().Cross(v);
- T uvx = T(2) * (y*v.z - z*v.y);
- T uvy = T(2) * (z*v.x - x*v.z);
- T uvz = T(2) * (x*v.y - y*v.x);
-
- // return v - Real()*uv + Imag().Cross(uv);
- return Vector3<T>(v.x - w*uvx + y*uvz - z*uvy,
- v.y - w*uvy + z*uvx - x*uvz,
- v.z - w*uvz + x*uvy - y*uvx);
- }
-
- // Inversed quaternion rotates in the opposite direction.
- Quat Inverted() const
- {
- return Quat(-x, -y, -z, w);
- }
-
- Quat Inverse() const
- {
- return Quat(-x, -y, -z, w);
- }
-
- // Sets this quaternion to the one rotates in the opposite direction.
- void Invert()
- {
- *this = Quat(-x, -y, -z, w);
- }
-
- // Time integration of constant angular velocity over dt
- Quat TimeIntegrate(Vector3<T> angularVelocity, T dt) const
- {
- // solution is: this * exp( omega*dt/2 ); FromRotationVector(v) gives exp(v*.5).
- return (*this * FastFromRotationVector(angularVelocity * dt, false)).Normalized();
- }
-
- // Time integration of constant angular acceleration and velocity over dt
- // These are the first two terms of the "Magnus expansion" of the solution
- //
- // o = o * exp( W=(W1 + W2 + W3+...) * 0.5 );
- //
- // omega1 = (omega + omegaDot*dt)
- // W1 = (omega + omega1)*dt/2
- // W2 = cross(omega, omega1)/12*dt^2 % (= -cross(omega_dot, omega)/12*dt^3)
- // Terms 3 and beyond are vanishingly small:
- // W3 = cross(omega_dot, cross(omega_dot, omega))/240*dt^5
- //
- Quat TimeIntegrate(Vector3<T> angularVelocity, Vector3<T> angularAcceleration, T dt) const
- {
- const Vector3<T>& omega = angularVelocity;
- const Vector3<T>& omegaDot = angularAcceleration;
-
- Vector3<T> omega1 = (omega + omegaDot * dt);
- Vector3<T> W = ( (omega + omega1) + omega.Cross(omega1) * (dt/T(6)) ) * (dt/T(2));
-
- // FromRotationVector(v) is exp(v*.5)
- return (*this * FastFromRotationVector(W, false)).Normalized();
- }
-
- // Decompose rotation into three rotations:
- // roll radians about Z axis, then pitch radians about X axis, then yaw radians about Y axis.
- // Call with nullptr if a return value is not needed.
- void GetYawPitchRoll(T* yaw, T* pitch, T* roll) const
- {
- return GetEulerAngles<Axis_Y, Axis_X, Axis_Z, Rotate_CCW, Handed_R>(yaw, pitch, roll);
- }
-
- // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of
- // axis rotations and the specified coordinate system. Right-handed coordinate system
- // is the default, with CCW rotations while looking in the negative axis direction.
- // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
- // Rotation order is c, b, a:
- // rotation c around axis A3
- // is followed by rotation b around axis A2
- // is followed by rotation a around axis A1
- // rotations are CCW or CW (D) in LH or RH coordinate system (S)
- //
- template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
- void GetEulerAngles(T *a, T *b, T *c) const
- {
- OVR_MATH_ASSERT(IsNormalized());
- OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)");
-
- T Q[3] = { x, y, z }; //Quaternion components x,y,z
-
- T ww = w*w;
- T Q11 = Q[A1]*Q[A1];
- T Q22 = Q[A2]*Q[A2];
- T Q33 = Q[A3]*Q[A3];
-
- T psign = T(-1);
- // Determine whether even permutation
- if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3))
- psign = T(1);
-
- T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]);
-
- T singularityRadius = Math<T>::SingularityRadius();
- if (s2 < T(-1) + singularityRadius)
- { // South pole singularity
- if (a) *a = T(0);
- if (b) *b = -S*D*((T)MATH_DOUBLE_PIOVER2);
- if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33 );
- }
- else if (s2 > T(1) - singularityRadius)
- { // North pole singularity
- if (a) *a = T(0);
- if (b) *b = S*D*((T)MATH_DOUBLE_PIOVER2);
- if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33);
- }
- else
- {
- if (a) *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2] * Q[A3]), ww + Q33 - Q11 - Q22);
- if (b) *b = S*D*asin(s2);
- if (c) *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1] * Q[A2]), ww + Q11 - Q22 - Q33);
- }
- }
-
- template <Axis A1, Axis A2, Axis A3, RotateDirection D>
- void GetEulerAngles(T *a, T *b, T *c) const
- { GetEulerAngles<A1, A2, A3, D, Handed_R>(a, b, c); }
-
- template <Axis A1, Axis A2, Axis A3>
- void GetEulerAngles(T *a, T *b, T *c) const
- { GetEulerAngles<A1, A2, A3, Rotate_CCW, Handed_R>(a, b, c); }
-
- // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of
- // axis rotations and the specified coordinate system. Right-handed coordinate system
- // is the default, with CCW rotations while looking in the negative axis direction.
- // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned.
- // rotation a around axis A1
- // is followed by rotation b around axis A2
- // is followed by rotation c around axis A1
- // Rotations are CCW or CW (D) in LH or RH coordinate system (S)
- template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
- void GetEulerAnglesABA(T *a, T *b, T *c) const
- {
- OVR_MATH_ASSERT(IsNormalized());
- OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2");
-
- T Q[3] = {x, y, z}; // Quaternion components
-
- // Determine the missing axis that was not supplied
- int m = 3 - A1 - A2;
-
- T ww = w*w;
- T Q11 = Q[A1]*Q[A1];
- T Q22 = Q[A2]*Q[A2];
- T Qmm = Q[m]*Q[m];
-
- T psign = T(-1);
- if ((A1 + 1) % 3 == A2) // Determine whether even permutation
- {
- psign = T(1);
- }
-
- T c2 = ww + Q11 - Q22 - Qmm;
- T singularityRadius = Math<T>::SingularityRadius();
- if (c2 < T(-1) + singularityRadius)
- { // South pole singularity
- if (a) *a = T(0);
- if (b) *b = S*D*((T)MATH_DOUBLE_PI);
- if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]),
- ww + Q22 - Q11 - Qmm);
- }
- else if (c2 > T(1) - singularityRadius)
- { // North pole singularity
- if (a) *a = T(0);
- if (b) *b = T(0);
- if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]),
- ww + Q22 - Q11 - Qmm);
- }
- else
- {
- if (a) *a = S*D*atan2(psign*w*Q[m] + Q[A1] * Q[A2],
- w*Q[A2] -psign*Q[A1]*Q[m]);
- if (b) *b = S*D*acos(c2);
- if (c) *c = S*D*atan2(-psign*w*Q[m] + Q[A1] * Q[A2],
- w*Q[A2] + psign*Q[A1]*Q[m]);
- }
- }
-};
-
-typedef Quat<float> Quatf;
-typedef Quat<double> Quatd;
-
-OVR_MATH_STATIC_ASSERT((sizeof(Quatf) == 4*sizeof(float)), "sizeof(Quatf) failure");
-OVR_MATH_STATIC_ASSERT((sizeof(Quatd) == 4*sizeof(double)), "sizeof(Quatd) failure");
-
-//-------------------------------------------------------------------------------------
-// ***** Pose
-//
-// Position and orientation combined.
-//
-// This structure needs to be the same size and layout on 32-bit and 64-bit arch.
-// Update OVR_PadCheck.cpp when updating this object.
-template<class T>
-class Pose
-{
-public:
- typedef typename CompatibleTypes<Pose<T> >::Type CompatibleType;
-
- Pose() { }
- Pose(const Quat<T>& orientation, const Vector3<T>& pos)
- : Rotation(orientation), Translation(pos) { }
- Pose(const Pose& s)
- : Rotation(s.Rotation), Translation(s.Translation) { }
- Pose(const Matrix3<T>& R, const Vector3<T>& t)
- : Rotation((Quat<T>)R), Translation(t) { }
- Pose(const CompatibleType& s)
- : Rotation(s.Orientation), Translation(s.Position) { }
-
- explicit Pose(const Pose<typename Math<T>::OtherFloatType> &s)
- : Rotation(s.Rotation), Translation(s.Translation)
- {
- // Ensure normalized rotation if converting from float to double
- if (sizeof(T) > sizeof(typename Math<T>::OtherFloatType))
- Rotation.Normalize();
- }
-
- static Pose Identity() { return Pose(Quat<T>(0, 0, 0, 1), Vector3<T>(0, 0, 0)); }
-
- void SetIdentity() { Rotation = Quat<T>(0, 0, 0, 1); Translation = Vector3<T>(0, 0, 0); }
-
- // used to make things obviously broken if someone tries to use the value
- void SetInvalid() { Rotation = Quat<T>(NAN, NAN, NAN, NAN); Translation = Vector3<T>(NAN, NAN, NAN); }
-
- bool IsEqual(const Pose&b, T tolerance = Math<T>::Tolerance()) const
- {
- return Translation.IsEqual(b.Translation, tolerance) && Rotation.IsEqual(b.Rotation, tolerance);
- }
-
- operator typename CompatibleTypes<Pose<T> >::Type () const
- {
- typename CompatibleTypes<Pose<T> >::Type result;
- result.Orientation = Rotation;
- result.Position = Translation;
- return result;
- }
-
- Quat<T> Rotation;
- Vector3<T> Translation;
-
- OVR_MATH_STATIC_ASSERT((sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))");
-
- void ToArray(T* arr) const
- {
- T temp[7] = { Rotation.x, Rotation.y, Rotation.z, Rotation.w, Translation.x, Translation.y, Translation.z };
- for (int i = 0; i < 7; i++) arr[i] = temp[i];
- }
-
- static Pose<T> FromArray(const T* v)
- {
- Quat<T> rotation(v[0], v[1], v[2], v[3]);
- Vector3<T> translation(v[4], v[5], v[6]);
- // Ensure rotation is normalized, in case it was originally a float, stored in a .json file, etc.
- return Pose<T>(rotation.Normalized(), translation);
- }
-
- Vector3<T> Rotate(const Vector3<T>& v) const
- {
- return Rotation.Rotate(v);
- }
-
- Vector3<T> InverseRotate(const Vector3<T>& v) const
- {
- return Rotation.InverseRotate(v);
- }
-
- Vector3<T> Translate(const Vector3<T>& v) const
- {
- return v + Translation;
- }
-
- Vector3<T> Transform(const Vector3<T>& v) const
- {
- return Rotate(v) + Translation;
- }
-
- Vector3<T> InverseTransform(const Vector3<T>& v) const
- {
- return InverseRotate(v - Translation);
- }
-
-
- Vector3<T> Apply(const Vector3<T>& v) const
- {
- return Transform(v);
- }
-
- Pose operator*(const Pose& other) const
- {
- return Pose(Rotation * other.Rotation, Apply(other.Translation));
- }
-
- Pose Inverted() const
- {
- Quat<T> inv = Rotation.Inverted();
- return Pose(inv, inv.Rotate(-Translation));
- }
-
- // Interpolation between two poses: translation is interpolated with Lerp(),
- // and rotations are interpolated with Slerp().
- Pose Lerp(const Pose& b, T s)
- {
- return Pose(Rotation.Slerp(b.Rotation, s), Translation.Lerp(b.Translation, s));
- }
-
- // Similar to Lerp above, except faster in case of small rotation differences. See Quat<T>::FastSlerp.
- Pose FastLerp(const Pose& b, T s)
- {
- return Pose(Rotation.FastSlerp(b.Rotation, s), Translation.Lerp(b.Translation, s));
- }
-
- Pose TimeIntegrate(const Vector3<T>& linearVelocity, const Vector3<T>& angularVelocity, T dt) const
- {
- return Pose(
- (Rotation * Quat<T>::FastFromRotationVector(angularVelocity * dt, false)).Normalized(),
- Translation + linearVelocity * dt);
- }
-
- Pose TimeIntegrate(const Vector3<T>& linearVelocity, const Vector3<T>& linearAcceleration,
- const Vector3<T>& angularVelocity, const Vector3<T>& angularAcceleration,
- T dt) const
- {
- return Pose(Rotation.TimeIntegrate(angularVelocity, angularAcceleration, dt),
- Translation + linearVelocity*dt + linearAcceleration*dt*dt * T(0.5));
- }
-};
-
-typedef Pose<float> Posef;
-typedef Pose<double> Posed;
-
-OVR_MATH_STATIC_ASSERT((sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), "sizeof(Posed) failure");
-OVR_MATH_STATIC_ASSERT((sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), "sizeof(Posef) failure");
-
-
-//-------------------------------------------------------------------------------------
-// ***** Matrix4
-//
-// Matrix4 is a 4x4 matrix used for 3d transformations and projections.
-// Translation stored in the last column.
-// The matrix is stored in row-major order in memory, meaning that values
-// of the first row are stored before the next one.
-//
-// The arrangement of the matrix is chosen to be in Right-Handed
-// coordinate system and counterclockwise rotations when looking down
-// the axis
-//
-// Transformation Order:
-// - Transformations are applied from right to left, so the expression
-// M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
-// followed by M2 and M1.
-//
-// Coordinate system: Right Handed
-//
-// Rotations: Counterclockwise when looking down the axis. All angles are in radians.
-//
-// | sx 01 02 tx | // First column (sx, 10, 20): Axis X basis vector.
-// | 10 sy 12 ty | // Second column (01, sy, 21): Axis Y basis vector.
-// | 20 21 sz tz | // Third columnt (02, 12, sz): Axis Z basis vector.
-// | 30 31 32 33 |
-//
-// The basis vectors are first three columns.
-
-template<class T>
-class Matrix4
-{
-public:
- typedef T ElementType;
- static const size_t Dimension = 4;
-
- T M[4][4];
-
- enum NoInitType { NoInit };
-
- // Construct with no memory initialization.
- Matrix4(NoInitType) { }
-
- // By default, we construct identity matrix.
- Matrix4()
- {
- M[0][0] = M[1][1] = M[2][2] = M[3][3] = T(1);
- M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0);
- M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0);
- M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(0);
- }
-
- Matrix4(T m11, T m12, T m13, T m14,
- T m21, T m22, T m23, T m24,
- T m31, T m32, T m33, T m34,
- T m41, T m42, T m43, T m44)
- {
- M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14;
- M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24;
- M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34;
- M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44;
- }
-
- Matrix4(T m11, T m12, T m13,
- T m21, T m22, T m23,
- T m31, T m32, T m33)
- {
- M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = T(0);
- M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = T(0);
- M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = T(0);
- M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(1);
- }
-
- explicit Matrix4(const Matrix3<T>& m)
- {
- M[0][0] = m.M[0][0]; M[0][1] = m.M[0][1]; M[0][2] = m.M[0][2]; M[0][3] = T(0);
- M[1][0] = m.M[1][0]; M[1][1] = m.M[1][1]; M[1][2] = m.M[1][2]; M[1][3] = T(0);
- M[2][0] = m.M[2][0]; M[2][1] = m.M[2][1]; M[2][2] = m.M[2][2]; M[2][3] = T(0);
- M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(1);
- }
-
- explicit Matrix4(const Quat<T>& q)
- {
- OVR_MATH_ASSERT(q.IsNormalized());
- T ww = q.w*q.w;
- T xx = q.x*q.x;
- T yy = q.y*q.y;
- T zz = q.z*q.z;
-
- M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); M[0][3] = T(0);
- M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); M[1][3] = T(0);
- M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; M[2][3] = T(0);
- M[3][0] = T(0); M[3][1] = T(0); M[3][2] = T(0); M[3][3] = T(1);
- }
-
- explicit Matrix4(const Pose<T>& p)
- {
- Matrix4 result(p.Rotation);
- result.SetTranslation(p.Translation);
- *this = result;
- }
-
-
- // C-interop support
- explicit Matrix4(const Matrix4<typename Math<T>::OtherFloatType> &src)
- {
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- M[i][j] = (T)src.M[i][j];
- }
-
- // C-interop support.
- Matrix4(const typename CompatibleTypes<Matrix4<T> >::Type& s)
- {
- OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)");
- memcpy(M, s.M, sizeof(M));
- }
-
- operator typename CompatibleTypes<Matrix4<T> >::Type () const
- {
- typename CompatibleTypes<Matrix4<T> >::Type result;
- OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)");
- memcpy(result.M, M, sizeof(M));
- return result;
- }
-
- void ToString(char* dest, size_t destsize) const
- {
- size_t pos = 0;
- for (int r=0; r<4; r++)
- {
- for (int c=0; c<4; c++)
- {
- pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
- }
- }
- }
-
- static Matrix4 FromString(const char* src)
- {
- Matrix4 result;
- if (src)
- {
- for (int r = 0; r < 4; r++)
- {
- for (int c = 0; c < 4; c++)
- {
- result.M[r][c] = (T)atof(src);
- while (*src && *src != ' ')
- {
- src++;
- }
- while (*src && *src == ' ')
- {
- src++;
- }
- }
- }
- }
- return result;
- }
-
- static Matrix4 Identity() { return Matrix4(); }
-
- void SetIdentity()
- {
- M[0][0] = M[1][1] = M[2][2] = M[3][3] = T(1);
- M[0][1] = M[1][0] = M[2][3] = M[3][1] = T(0);
- M[0][2] = M[1][2] = M[2][0] = M[3][2] = T(0);
- M[0][3] = M[1][3] = M[2][1] = M[3][0] = T(0);
- }
-
- void SetXBasis(const Vector3<T>& v)
- {
- M[0][0] = v.x;
- M[1][0] = v.y;
- M[2][0] = v.z;
- }
- Vector3<T> GetXBasis() const
- {
- return Vector3<T>(M[0][0], M[1][0], M[2][0]);
- }
-
- void SetYBasis(const Vector3<T> & v)
- {
- M[0][1] = v.x;
- M[1][1] = v.y;
- M[2][1] = v.z;
- }
- Vector3<T> GetYBasis() const
- {
- return Vector3<T>(M[0][1], M[1][1], M[2][1]);
- }
-
- void SetZBasis(const Vector3<T> & v)
- {
- M[0][2] = v.x;
- M[1][2] = v.y;
- M[2][2] = v.z;
- }
- Vector3<T> GetZBasis() const
- {
- return Vector3<T>(M[0][2], M[1][2], M[2][2]);
- }
-
- bool operator== (const Matrix4& b) const
- {
- bool isEqual = true;
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- isEqual &= (M[i][j] == b.M[i][j]);
-
- return isEqual;
- }
-
- Matrix4 operator+ (const Matrix4& b) const
- {
- Matrix4 result(*this);
- result += b;
- return result;
- }
-
- Matrix4& operator+= (const Matrix4& b)
- {
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- M[i][j] += b.M[i][j];
- return *this;
- }
-
- Matrix4 operator- (const Matrix4& b) const
- {
- Matrix4 result(*this);
- result -= b;
- return result;
- }
-
- Matrix4& operator-= (const Matrix4& b)
- {
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- M[i][j] -= b.M[i][j];
- return *this;
- }
-
- // Multiplies two matrices into destination with minimum copying.
- static Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b)
- {
- OVR_MATH_ASSERT((d != &a) && (d != &b));
- int i = 0;
- do {
- d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0] + a.M[i][3] * b.M[3][0];
- d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1] + a.M[i][3] * b.M[3][1];
- d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2] + a.M[i][3] * b.M[3][2];
- d->M[i][3] = a.M[i][0] * b.M[0][3] + a.M[i][1] * b.M[1][3] + a.M[i][2] * b.M[2][3] + a.M[i][3] * b.M[3][3];
- } while((++i) < 4);
-
- return *d;
- }
-
- Matrix4 operator* (const Matrix4& b) const
- {
- Matrix4 result(Matrix4::NoInit);
- Multiply(&result, *this, b);
- return result;
- }
-
- Matrix4& operator*= (const Matrix4& b)
- {
- return Multiply(this, Matrix4(*this), b);
- }
-
- Matrix4 operator* (T s) const
- {
- Matrix4 result(*this);
- result *= s;
- return result;
- }
-
- Matrix4& operator*= (T s)
- {
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- M[i][j] *= s;
- return *this;
- }
-
-
- Matrix4 operator/ (T s) const
- {
- Matrix4 result(*this);
- result /= s;
- return result;
- }
-
- Matrix4& operator/= (T s)
- {
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
- M[i][j] /= s;
- return *this;
- }
-
- Vector3<T> Transform(const Vector3<T>& v) const
- {
- const T rcpW = T(1) / (M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3]);
- return Vector3<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3]) * rcpW,
- (M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3]) * rcpW,
- (M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]) * rcpW);
- }
-
- Vector4<T> Transform(const Vector4<T>& v) const
- {
- return Vector4<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3] * v.w,
- M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3] * v.w,
- M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3] * v.w,
- M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3] * v.w);
- }
-
- Matrix4 Transposed() const
- {
- return Matrix4(M[0][0], M[1][0], M[2][0], M[3][0],
- M[0][1], M[1][1], M[2][1], M[3][1],
- M[0][2], M[1][2], M[2][2], M[3][2],
- M[0][3], M[1][3], M[2][3], M[3][3]);
- }
-
- void Transpose()
- {
- *this = Transposed();
- }
-
-
- T SubDet (const size_t* rows, const size_t* cols) const
- {
- return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]])
- - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]])
- + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]);
- }
-
- T Cofactor(size_t I, size_t J) const
- {
- const size_t indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}};
- return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]);
- }
-
- T Determinant() const
- {
- return M[0][0] * Cofactor(0,0) + M[0][1] * Cofactor(0,1) + M[0][2] * Cofactor(0,2) + M[0][3] * Cofactor(0,3);
- }
-
- Matrix4 Adjugated() const
- {
- return Matrix4(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0),
- Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1),
- Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2),
- Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3));
- }
-
- Matrix4 Inverted() const
- {
- T det = Determinant();
- OVR_MATH_ASSERT(det != 0);
- return Adjugated() * (T(1)/det);
- }
-
- void Invert()
- {
- *this = Inverted();
- }
-
- // This is more efficient than general inverse, but ONLY works
- // correctly if it is a homogeneous transform matrix (rot + trans)
- Matrix4 InvertedHomogeneousTransform() const
- {
- // Make the inverse rotation matrix
- Matrix4 rinv = this->Transposed();
- rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = T(0);
- // Make the inverse translation matrix
- Vector3<T> tvinv(-M[0][3],-M[1][3],-M[2][3]);
- Matrix4 tinv = Matrix4::Translation(tvinv);
- return rinv * tinv; // "untranslate", then "unrotate"
- }
-
- // This is more efficient than general inverse, but ONLY works
- // correctly if it is a homogeneous transform matrix (rot + trans)
- void InvertHomogeneousTransform()
- {
- *this = InvertedHomogeneousTransform();
- }
-
- // Matrix to Euler Angles conversion
- // a,b,c, are the YawPitchRoll angles to be returned
- // rotation a around axis A1
- // is followed by rotation b around axis A2
- // is followed by rotation c around axis A3
- // rotations are CCW or CW (D) in LH or RH coordinate system (S)
- template <Axis A1, Axis A2, Axis A3, RotateDirection D, HandedSystem S>
- void ToEulerAngles(T *a, T *b, T *c) const
- {
- OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)");
-
- T psign = T(-1);
- if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation
- psign = T(1);
-
- T pm = psign*M[A1][A3];
- T singularityRadius = Math<T>::SingularityRadius();
- if (pm < T(-1) + singularityRadius)
- { // South pole singularity
- *a = T(0);
- *b = -S*D*((T)MATH_DOUBLE_PIOVER2);
- *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
- }
- else if (pm > T(1) - singularityRadius)
- { // North pole singularity
- *a = T(0);
- *b = S*D*((T)MATH_DOUBLE_PIOVER2);
- *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] );
- }
- else
- { // Normal case (nonsingular)
- *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] );
- *b = S*D*asin(pm);
- *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] );
- }
- }
-
- // Matrix to Euler Angles conversion
- // a,b,c, are the YawPitchRoll angles to be returned
- // rotation a around axis A1
- // is followed by rotation b around axis A2
- // is followed by rotation c around axis A1
- // rotations are CCW or CW (D) in LH or RH coordinate system (S)
- template <Axis A1, Axis A2, RotateDirection D, HandedSystem S>
- void ToEulerAnglesABA(T *a, T *b, T *c) const
- {
- OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2");
-
- // Determine the axis that was not supplied
- int m = 3 - A1 - A2;
-
- T psign = T(-1);
- if ((A1 + 1) % 3 == A2) // Determine whether even permutation
- psign = T(1);
-
- T c2 = M[A1][A1];
- T singularityRadius = Math<T>::SingularityRadius();
- if (c2 < T(-1) + singularityRadius)
- { // South pole singularity
- *a = T(0);
- *b = S*D*((T)MATH_DOUBLE_PI);
- *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
- }
- else if (c2 > T(1) - singularityRadius)
- { // North pole singularity
- *a = T(0);
- *b = T(0);
- *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]);
- }
- else
- { // Normal case (nonsingular)
- *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]);
- *b = S*D*acos(c2);
- *c = S*D*atan2( M[A1][A2],psign*M[A1][m]);
- }
- }
-
- // Creates a matrix that converts the vertices from one coordinate system
- // to another.
- static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from)
- {
- // Holds axis values from the 'to' structure
- int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis };
-
- // The inverse of the toArray
- int inv[4];
- inv[0] = inv[abs(to.XAxis)] = 0;
- inv[abs(to.YAxis)] = 1;
- inv[abs(to.ZAxis)] = 2;
-
- Matrix4 m(0, 0, 0,
- 0, 0, 0,
- 0, 0, 0);
-
- // Only three values in the matrix need to be changed to 1 or -1.
- m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis/toArray[inv[abs(from.XAxis)]]);
- m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis/toArray[inv[abs(from.YAxis)]]);
- m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis/toArray[inv[abs(from.ZAxis)]]);
- return m;
- }
-
-
- // Creates a matrix for translation by vector
- static Matrix4 Translation(const Vector3<T>& v)
- {
- Matrix4 t;
- t.M[0][3] = v.x;
- t.M[1][3] = v.y;
- t.M[2][3] = v.z;
- return t;
- }
-
- // Creates a matrix for translation by vector
- static Matrix4 Translation(T x, T y, T z = T(0))
- {
- Matrix4 t;
- t.M[0][3] = x;
- t.M[1][3] = y;
- t.M[2][3] = z;
- return t;
- }
-
- // Sets the translation part
- void SetTranslation(const Vector3<T>& v)
- {
- M[0][3] = v.x;
- M[1][3] = v.y;
- M[2][3] = v.z;
- }
-
- Vector3<T> GetTranslation() const
- {
- return Vector3<T>( M[0][3], M[1][3], M[2][3] );
- }
-
- // Creates a matrix for scaling by vector
- static Matrix4 Scaling(const Vector3<T>& v)
- {
- Matrix4 t;
- t.M[0][0] = v.x;
- t.M[1][1] = v.y;
- t.M[2][2] = v.z;
- return t;
- }
-
- // Creates a matrix for scaling by vector
- static Matrix4 Scaling(T x, T y, T z)
- {
- Matrix4 t;
- t.M[0][0] = x;
- t.M[1][1] = y;
- t.M[2][2] = z;
- return t;
- }
-
- // Creates a matrix for scaling by constant
- static Matrix4 Scaling(T s)
- {
- Matrix4 t;
- t.M[0][0] = s;
- t.M[1][1] = s;
- t.M[2][2] = s;
- return t;
- }
-
- // Simple L1 distance in R^12
- T Distance(const Matrix4& m2) const
- {
- T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]);
- d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]);
- d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]);
- d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]);
- d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]);
- d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]);
- d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]);
- d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]);
- return d;
- }
-
- // Creates a rotation matrix rotating around the X axis by 'angle' radians.
- // Just for quick testing. Not for final API. Need to remove case.
- static Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s)
- {
- T sina = s * d *sin(angle);
- T cosa = cos(angle);
-
- switch(A)
- {
- case Axis_X:
- return Matrix4(1, 0, 0,
- 0, cosa, -sina,
- 0, sina, cosa);
- case Axis_Y:
- return Matrix4(cosa, 0, sina,
- 0, 1, 0,
- -sina, 0, cosa);
- case Axis_Z:
- return Matrix4(cosa, -sina, 0,
- sina, cosa, 0,
- 0, 0, 1);
- default:
- return Matrix4();
- }
- }
-
-
- // Creates a rotation matrix rotating around the X axis by 'angle' radians.
- // Rotation direction is depends on the coordinate system:
- // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
- // while looking in the negative axis direction. This is the
- // same as looking down from positive axis values towards origin.
- // LHS: Positive angle values rotate clock-wise (CW), while looking in the
- // negative axis direction.
- static Matrix4 RotationX(T angle)
- {
- T sina = sin(angle);
- T cosa = cos(angle);
- return Matrix4(1, 0, 0,
- 0, cosa, -sina,
- 0, sina, cosa);
- }
-
- // Creates a rotation matrix rotating around the Y axis by 'angle' radians.
- // Rotation direction is depends on the coordinate system:
- // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
- // while looking in the negative axis direction. This is the
- // same as looking down from positive axis values towards origin.
- // LHS: Positive angle values rotate clock-wise (CW), while looking in the
- // negative axis direction.
- static Matrix4 RotationY(T angle)
- {
- T sina = (T)sin(angle);
- T cosa = (T)cos(angle);
- return Matrix4(cosa, 0, sina,
- 0, 1, 0,
- -sina, 0, cosa);
- }
-
- // Creates a rotation matrix rotating around the Z axis by 'angle' radians.
- // Rotation direction is depends on the coordinate system:
- // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW),
- // while looking in the negative axis direction. This is the
- // same as looking down from positive axis values towards origin.
- // LHS: Positive angle values rotate clock-wise (CW), while looking in the
- // negative axis direction.
- static Matrix4 RotationZ(T angle)
- {
- T sina = sin(angle);
- T cosa = cos(angle);
- return Matrix4(cosa, -sina, 0,
- sina, cosa, 0,
- 0, 0, 1);
- }
-
- // LookAtRH creates a View transformation matrix for right-handed coordinate system.
- // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
- // specifying the up vector. The resulting matrix should be used with PerspectiveRH
- // projection.
- static Matrix4 LookAtRH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
- {
- Vector3<T> z = (eye - at).Normalized(); // Forward
- Vector3<T> x = up.Cross(z).Normalized(); // Right
- Vector3<T> y = z.Cross(x);
-
- Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)),
- y.x, y.y, y.z, -(y.Dot(eye)),
- z.x, z.y, z.z, -(z.Dot(eye)),
- 0, 0, 0, 1 );
- return m;
- }
-
- // LookAtLH creates a View transformation matrix for left-handed coordinate system.
- // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up'
- // specifying the up vector.
- static Matrix4 LookAtLH(const Vector3<T>& eye, const Vector3<T>& at, const Vector3<T>& up)
- {
- Vector3<T> z = (at - eye).Normalized(); // Forward
- Vector3<T> x = up.Cross(z).Normalized(); // Right
- Vector3<T> y = z.Cross(x);
-
- Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)),
- y.x, y.y, y.z, -(y.Dot(eye)),
- z.x, z.y, z.z, -(z.Dot(eye)),
- 0, 0, 0, 1 );
- return m;
- }
-
- // PerspectiveRH creates a right-handed perspective projection matrix that can be
- // used with the Oculus sample renderer.
- // yfov - Specifies vertical field of view in radians.
- // aspect - Screen aspect ration, which is usually width/height for square pixels.
- // Note that xfov = yfov * aspect.
- // znear - Absolute value of near Z clipping clipping range.
- // zfar - Absolute value of far Z clipping clipping range (larger then near).
- // Even though RHS usually looks in the direction of negative Z, positive values
- // are expected for znear and zfar.
- static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar)
- {
- Matrix4 m;
- T tanHalfFov = tan(yfov * T(0.5));
-
- m.M[0][0] = T(1) / (aspect * tanHalfFov);
- m.M[1][1] = T(1) / tanHalfFov;
- m.M[2][2] = zfar / (znear - zfar);
- m.M[3][2] = T(-1);
- m.M[2][3] = (zfar * znear) / (znear - zfar);
- m.M[3][3] = T(0);
-
- // Note: Post-projection matrix result assumes Left-Handed coordinate system,
- // with Y up, X right and Z forward. This supports positive z-buffer values.
- // This is the case even for RHS coordinate input.
- return m;
- }
-
- // PerspectiveLH creates a left-handed perspective projection matrix that can be
- // used with the Oculus sample renderer.
- // yfov - Specifies vertical field of view in radians.
- // aspect - Screen aspect ration, which is usually width/height for square pixels.
- // Note that xfov = yfov * aspect.
- // znear - Absolute value of near Z clipping clipping range.
- // zfar - Absolute value of far Z clipping clipping range (larger then near).
- static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar)
- {
- Matrix4 m;
- T tanHalfFov = tan(yfov * T(0.5));
-
- m.M[0][0] = T(1) / (aspect * tanHalfFov);
- m.M[1][1] = T(1) / tanHalfFov;
- //m.M[2][2] = zfar / (znear - zfar);
- m.M[2][2] = zfar / (zfar - znear);
- m.M[3][2] = T(-1);
- m.M[2][3] = (zfar * znear) / (znear - zfar);
- m.M[3][3] = T(0);
-
- // Note: Post-projection matrix result assumes Left-Handed coordinate system,
- // with Y up, X right and Z forward. This supports positive z-buffer values.
- // This is the case even for RHS coordinate input.
- return m;
- }
-
- static Matrix4 Ortho2D(T w, T h)
- {
- Matrix4 m;
- m.M[0][0] = T(2.0)/w;
- m.M[1][1] = T(-2.0)/h;
- m.M[0][3] = T(-1.0);
- m.M[1][3] = T(1.0);
- m.M[2][2] = T(0);
- return m;
- }
-};
-
-typedef Matrix4<float> Matrix4f;
-typedef Matrix4<double> Matrix4d;
-
-//-------------------------------------------------------------------------------------
-// ***** Matrix3
-//
-// Matrix3 is a 3x3 matrix used for representing a rotation matrix.
-// The matrix is stored in row-major order in memory, meaning that values
-// of the first row are stored before the next one.
-//
-// The arrangement of the matrix is chosen to be in Right-Handed
-// coordinate system and counterclockwise rotations when looking down
-// the axis
-//
-// Transformation Order:
-// - Transformations are applied from right to left, so the expression
-// M1 * M2 * M3 * V means that the vector V is transformed by M3 first,
-// followed by M2 and M1.
-//
-// Coordinate system: Right Handed
-//
-// Rotations: Counterclockwise when looking down the axis. All angles are in radians.
-
-template<class T>
-class Matrix3
-{
-public:
- typedef T ElementType;
- static const size_t Dimension = 3;
-
- T M[3][3];
-
- enum NoInitType { NoInit };
-
- // Construct with no memory initialization.
- Matrix3(NoInitType) { }
-
- // By default, we construct identity matrix.
- Matrix3()
- {
- M[0][0] = M[1][1] = M[2][2] = T(1);
- M[0][1] = M[1][0] = M[2][0] = T(0);
- M[0][2] = M[1][2] = M[2][1] = T(0);
- }
-
- Matrix3(T m11, T m12, T m13,
- T m21, T m22, T m23,
- T m31, T m32, T m33)
- {
- M[0][0] = m11; M[0][1] = m12; M[0][2] = m13;
- M[1][0] = m21; M[1][1] = m22; M[1][2] = m23;
- M[2][0] = m31; M[2][1] = m32; M[2][2] = m33;
- }
-
- // Construction from X, Y, Z basis vectors
- Matrix3(const Vector3<T>& xBasis, const Vector3<T>& yBasis, const Vector3<T>& zBasis)
- {
- M[0][0] = xBasis.x; M[0][1] = yBasis.x; M[0][2] = zBasis.x;
- M[1][0] = xBasis.y; M[1][1] = yBasis.y; M[1][2] = zBasis.y;
- M[2][0] = xBasis.z; M[2][1] = yBasis.z; M[2][2] = zBasis.z;
- }
-
- explicit Matrix3(const Quat<T>& q)
- {
- OVR_MATH_ASSERT(q.IsNormalized());
- const T tx = q.x+q.x, ty = q.y+q.y, tz = q.z+q.z;
- const T twx = q.w*tx, twy = q.w*ty, twz = q.w*tz;
- const T txx = q.x*tx, txy = q.x*ty, txz = q.x*tz;
- const T tyy = q.y*ty, tyz = q.y*tz, tzz = q.z*tz;
- M[0][0] = T(1) - (tyy + tzz); M[0][1] = txy - twz; M[0][2] = txz + twy;
- M[1][0] = txy + twz; M[1][1] = T(1) - (txx + tzz); M[1][2] = tyz - twx;
- M[2][0] = txz - twy; M[2][1] = tyz + twx; M[2][2] = T(1) - (txx + tyy);
- }
-
- inline explicit Matrix3(T s)
- {
- M[0][0] = M[1][1] = M[2][2] = s;
- M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = T(0);
- }
-
- Matrix3(T m11, T m22, T m33)
- {
- M[0][0] = m11; M[0][1] = T(0); M[0][2] = T(0);
- M[1][0] = T(0); M[1][1] = m22; M[1][2] = T(0);
- M[2][0] = T(0); M[2][1] = T(0); M[2][2] = m33;
- }
-
- explicit Matrix3(const Matrix3<typename Math<T>::OtherFloatType> &src)
- {
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- M[i][j] = (T)src.M[i][j];
- }
-
- // C-interop support.
- Matrix3(const typename CompatibleTypes<Matrix3<T> >::Type& s)
- {
- OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)");
- memcpy(M, s.M, sizeof(M));
- }
-
- operator const typename CompatibleTypes<Matrix3<T> >::Type () const
- {
- typename CompatibleTypes<Matrix3<T> >::Type result;
- OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)");
- memcpy(result.M, M, sizeof(M));
- return result;
- }
-
- T operator()(int i, int j) const { return M[i][j]; }
- T& operator()(int i, int j) { return M[i][j]; }
-
- void ToString(char* dest, size_t destsize) const
- {
- size_t pos = 0;
- for (int r=0; r<3; r++)
- {
- for (int c=0; c<3; c++)
- pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]);
- }
- }
-
- static Matrix3 FromString(const char* src)
- {
- Matrix3 result;
- if (src)
- {
- for (int r=0; r<3; r++)
- {
- for (int c=0; c<3; c++)
- {
- result.M[r][c] = (T)atof(src);
- while (*src && *src != ' ')
- src++;
- while (*src && *src == ' ')
- src++;
- }
- }
- }
- return result;
- }
-
- static Matrix3 Identity() { return Matrix3(); }
-
- void SetIdentity()
- {
- M[0][0] = M[1][1] = M[2][2] = T(1);
- M[0][1] = M[1][0] = M[2][0] = T(0);
- M[0][2] = M[1][2] = M[2][1] = T(0);
- }
-
- static Matrix3 Diagonal(T m00, T m11, T m22)
- {
- return Matrix3(m00, 0, 0,
- 0, m11, 0,
- 0, 0, m22);
- }
- static Matrix3 Diagonal(const Vector3<T>& v) { return Diagonal(v.x, v.y, v.z); }
-
- T Trace() const { return M[0][0] + M[1][1] + M[2][2]; }
-
- bool operator== (const Matrix3& b) const
- {
- bool isEqual = true;
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- isEqual &= (M[i][j] == b.M[i][j]);
- }
-
- return isEqual;
- }
-
- Matrix3 operator+ (const Matrix3& b) const
- {
- Matrix3<T> result(*this);
- result += b;
- return result;
- }
-
- Matrix3& operator+= (const Matrix3& b)
- {
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- M[i][j] += b.M[i][j];
- return *this;
- }
-
- void operator= (const Matrix3& b)
- {
- for (int i = 0; i < 3; i++)
- for (int j = 0; j < 3; j++)
- M[i][j] = b.M[i][j];
- }
-
- Matrix3 operator- (const Matrix3& b) const
- {
- Matrix3 result(*this);
- result -= b;
- return result;
- }
-
- Matrix3& operator-= (const Matrix3& b)
- {
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- M[i][j] -= b.M[i][j];
- }
-
- return *this;
- }
-
- // Multiplies two matrices into destination with minimum copying.
- static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b)
- {
- OVR_MATH_ASSERT((d != &a) && (d != &b));
- int i = 0;
- do {
- d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0];
- d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1];
- d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2];
- } while((++i) < 3);
-
- return *d;
- }
-
- Matrix3 operator* (const Matrix3& b) const
- {
- Matrix3 result(Matrix3::NoInit);
- Multiply(&result, *this, b);
- return result;
- }
-
- Matrix3& operator*= (const Matrix3& b)
- {
- return Multiply(this, Matrix3(*this), b);
- }
-
- Matrix3 operator* (T s) const
- {
- Matrix3 result(*this);
- result *= s;
- return result;
- }
-
- Matrix3& operator*= (T s)
- {
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- M[i][j] *= s;
- }
-
- return *this;
- }
-
- Vector3<T> operator* (const Vector3<T> &b) const
- {
- Vector3<T> result;
- result.x = M[0][0]*b.x + M[0][1]*b.y + M[0][2]*b.z;
- result.y = M[1][0]*b.x + M[1][1]*b.y + M[1][2]*b.z;
- result.z = M[2][0]*b.x + M[2][1]*b.y + M[2][2]*b.z;
-
- return result;
- }
-
- Matrix3 operator/ (T s) const
- {
- Matrix3 result(*this);
- result /= s;
- return result;
- }
-
- Matrix3& operator/= (T s)
- {
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- M[i][j] /= s;
- }
-
- return *this;
- }
-
- Vector2<T> Transform(const Vector2<T>& v) const
- {
- const T rcpZ = T(1) / (M[2][0] * v.x + M[2][1] * v.y + M[2][2]);
- return Vector2<T>((M[0][0] * v.x + M[0][1] * v.y + M[0][2]) * rcpZ,
- (M[1][0] * v.x + M[1][1] * v.y + M[1][2]) * rcpZ);
- }
-
- Vector3<T> Transform(const Vector3<T>& v) const
- {
- return Vector3<T>(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z,
- M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z,
- M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z);
- }
-
- Matrix3 Transposed() const
- {
- return Matrix3(M[0][0], M[1][0], M[2][0],
- M[0][1], M[1][1], M[2][1],
- M[0][2], M[1][2], M[2][2]);
- }
-
- void Transpose()
- {
- *this = Transposed();
- }
-
-
- T SubDet (const size_t* rows, const size_t* cols) const
- {
- return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]])
- - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]])
- + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]);
- }
-
-
- // M += a*b.t()
- inline void Rank1Add(const Vector3<T> &a, const Vector3<T> &b)
- {
- M[0][0] += a.x*b.x; M[0][1] += a.x*b.y; M[0][2] += a.x*b.z;
- M[1][0] += a.y*b.x; M[1][1] += a.y*b.y; M[1][2] += a.y*b.z;
- M[2][0] += a.z*b.x; M[2][1] += a.z*b.y; M[2][2] += a.z*b.z;
- }
-
- // M -= a*b.t()
- inline void Rank1Sub(const Vector3<T> &a, const Vector3<T> &b)
- {
- M[0][0] -= a.x*b.x; M[0][1] -= a.x*b.y; M[0][2] -= a.x*b.z;
- M[1][0] -= a.y*b.x; M[1][1] -= a.y*b.y; M[1][2] -= a.y*b.z;
- M[2][0] -= a.z*b.x; M[2][1] -= a.z*b.y; M[2][2] -= a.z*b.z;
- }
-
- inline Vector3<T> Col(int c) const
- {
- return Vector3<T>(M[0][c], M[1][c], M[2][c]);
- }
-
- inline Vector3<T> Row(int r) const
- {
- return Vector3<T>(M[r][0], M[r][1], M[r][2]);
- }
-
- inline Vector3<T> GetColumn(int c) const
- {
- return Vector3<T>(M[0][c], M[1][c], M[2][c]);
- }
-
- inline Vector3<T> GetRow(int r) const
- {
- return Vector3<T>(M[r][0], M[r][1], M[r][2]);
- }
-
- inline void SetColumn(int c, const Vector3<T>& v)
- {
- M[0][c] = v.x;
- M[1][c] = v.y;
- M[2][c] = v.z;
- }
-
- inline void SetRow(int r, const Vector3<T>& v)
- {
- M[r][0] = v.x;
- M[r][1] = v.y;
- M[r][2] = v.z;
- }
-
- inline T Determinant() const
- {
- const Matrix3<T>& m = *this;
- T d;
-
- d = m.M[0][0] * (m.M[1][1]*m.M[2][2] - m.M[1][2] * m.M[2][1]);
- d -= m.M[0][1] * (m.M[1][0]*m.M[2][2] - m.M[1][2] * m.M[2][0]);
- d += m.M[0][2] * (m.M[1][0]*m.M[2][1] - m.M[1][1] * m.M[2][0]);
-
- return d;
- }
-
- inline Matrix3<T> Inverse() const
- {
- Matrix3<T> a;
- const Matrix3<T>& m = *this;
- T d = Determinant();
-
- OVR_MATH_ASSERT(d != 0);
- T s = T(1)/d;
-
- a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]);
- a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]);
- a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]);
-
- a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]);
- a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]);
- a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]);
-
- a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]);
- a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]);
- a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]);
-
- return a;
- }
-
- // Outer Product of two column vectors: a * b.Transpose()
- static Matrix3 OuterProduct(const Vector3<T>& a, const Vector3<T>& b)
- {
- return Matrix3(a.x*b.x, a.x*b.y, a.x*b.z,
- a.y*b.x, a.y*b.y, a.y*b.z,
- a.z*b.x, a.z*b.y, a.z*b.z);
- }
-
- // Vector cross product as a premultiply matrix:
- // L.Cross(R) = LeftCrossAsMatrix(L) * R
- static Matrix3 LeftCrossAsMatrix(const Vector3<T>& L)
- {
- return Matrix3(
- T(0), -L.z, +L.y,
- +L.z, T(0), -L.x,
- -L.y, +L.x, T(0));
- }
-
- // Vector cross product as a premultiply matrix:
- // L.Cross(R) = RightCrossAsMatrix(R) * L
- static Matrix3 RightCrossAsMatrix(const Vector3<T>& R)
- {
- return Matrix3(
- T(0), +R.z, -R.y,
- -R.z, T(0), +R.x,
- +R.y, -R.x, T(0));
- }
-
- // Angle in radians of a rotation matrix
- // Uses identity trace(a) = 2*cos(theta) + 1
- T Angle() const
- {
- return Acos((Trace() - T(1)) * T(0.5));
- }
-
- // Angle in radians between two rotation matrices
- T Angle(const Matrix3& b) const
- {
- // Compute trace of (this->Transposed() * b)
- // This works out to sum of products of elements.
- T trace = T(0);
- for (int i = 0; i < 3; i++)
- {
- for (int j = 0; j < 3; j++)
- {
- trace += M[i][j] * b.M[i][j];
- }
- }
- return Acos((trace - T(1)) * T(0.5));
- }
-};
-
-typedef Matrix3<float> Matrix3f;
-typedef Matrix3<double> Matrix3d;
-
-//-------------------------------------------------------------------------------------
-// ***** Matrix2
-
-template<class T>
-class Matrix2
-{
-public:
- typedef T ElementType;
- static const size_t Dimension = 2;
-
- T M[2][2];
-
- enum NoInitType { NoInit };
-
- // Construct with no memory initialization.
- Matrix2(NoInitType) { }
-
- // By default, we construct identity matrix.
- Matrix2()
- {
- M[0][0] = M[1][1] = T(1);
- M[0][1] = M[1][0] = T(0);
- }
-
- Matrix2(T m11, T m12,
- T m21, T m22)
- {
- M[0][0] = m11; M[0][1] = m12;
- M[1][0] = m21; M[1][1] = m22;
- }
-
- // Construction from X, Y basis vectors
- Matrix2(const Vector2<T>& xBasis, const Vector2<T>& yBasis)
- {
- M[0][0] = xBasis.x; M[0][1] = yBasis.x;
- M[1][0] = xBasis.y; M[1][1] = yBasis.y;
- }
-
- explicit Matrix2(T s)
- {
- M[0][0] = M[1][1] = s;
- M[0][1] = M[1][0] = T(0);
- }
-
- Matrix2(T m11, T m22)
- {
- M[0][0] = m11; M[0][1] = T(0);
- M[1][0] = T(0); M[1][1] = m22;
- }
-
- explicit Matrix2(const Matrix2<typename Math<T>::OtherFloatType> &src)
- {
- M[0][0] = T(src.M[0][0]); M[0][1] = T(src.M[0][1]);
- M[1][0] = T(src.M[1][0]); M[1][1] = T(src.M[1][1]);
- }
-
- // C-interop support
- Matrix2(const typename CompatibleTypes<Matrix2<T> >::Type& s)
- {
- OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix2), "sizeof(s) == sizeof(Matrix2)");
- memcpy(M, s.M, sizeof(M));
- }
-
- operator const typename CompatibleTypes<Matrix2<T> >::Type() const
- {
- typename CompatibleTypes<Matrix2<T> >::Type result;
- OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix2), "sizeof(result) == sizeof(Matrix2)");
- memcpy(result.M, M, sizeof(M));
- return result;
- }
-
- T operator()(int i, int j) const { return M[i][j]; }
- T& operator()(int i, int j) { return M[i][j]; }
- const T* operator[](int i) const { return M[i]; }
- T* operator[](int i) { return M[i]; }
-
- static Matrix2 Identity() { return Matrix2(); }
-
- void SetIdentity()
- {
- M[0][0] = M[1][1] = T(1);
- M[0][1] = M[1][0] = T(0);
- }
-
- static Matrix2 Diagonal(T m00, T m11)
- {
- return Matrix2(m00, m11);
- }
- static Matrix2 Diagonal(const Vector2<T>& v) { return Matrix2(v.x, v.y); }
-
- T Trace() const { return M[0][0] + M[1][1]; }
-
- bool operator== (const Matrix2& b) const
- {
- return M[0][0] == b.M[0][0] && M[0][1] == b.M[0][1] &&
- M[1][0] == b.M[1][0] && M[1][1] == b.M[1][1];
- }
-
- Matrix2 operator+ (const Matrix2& b) const
- {
- return Matrix2(M[0][0] + b.M[0][0], M[0][1] + b.M[0][1],
- M[1][0] + b.M[1][0], M[1][1] + b.M[1][1]);
- }
-
- Matrix2& operator+= (const Matrix2& b)
- {
- M[0][0] += b.M[0][0]; M[0][1] += b.M[0][1];
- M[1][0] += b.M[1][0]; M[1][1] += b.M[1][1];
- return *this;
- }
-
- void operator= (const Matrix2& b)
- {
- M[0][0] = b.M[0][0]; M[0][1] = b.M[0][1];
- M[1][0] = b.M[1][0]; M[1][1] = b.M[1][1];
- }
-
- Matrix2 operator- (const Matrix2& b) const
- {
- return Matrix2(M[0][0] - b.M[0][0], M[0][1] - b.M[0][1],
- M[1][0] - b.M[1][0], M[1][1] - b.M[1][1]);
- }
-
- Matrix2& operator-= (const Matrix2& b)
- {
- M[0][0] -= b.M[0][0]; M[0][1] -= b.M[0][1];
- M[1][0] -= b.M[1][0]; M[1][1] -= b.M[1][1];
- return *this;
- }
-
- Matrix2 operator* (const Matrix2& b) const
- {
- return Matrix2(M[0][0] * b.M[0][0] + M[0][1] * b.M[1][0], M[0][0] * b.M[0][1] + M[0][1] * b.M[1][1],
- M[1][0] * b.M[0][0] + M[1][1] * b.M[1][0], M[1][0] * b.M[0][1] + M[1][1] * b.M[1][1]);
- }
-
- Matrix2& operator*= (const Matrix2& b)
- {
- *this = *this * b;
- return *this;
- }
-
- Matrix2 operator* (T s) const
- {
- return Matrix2(M[0][0] * s, M[0][1] * s,
- M[1][0] * s, M[1][1] * s);
- }
-
- Matrix2& operator*= (T s)
- {
- M[0][0] *= s; M[0][1] *= s;
- M[1][0] *= s; M[1][1] *= s;
- return *this;
- }
-
- Matrix2 operator/ (T s) const
- {
- return *this * (T(1) / s);
- }
-
- Matrix2& operator/= (T s)
- {
- return *this *= (T(1) / s);
- }
-
- Vector2<T> operator* (const Vector2<T> &b) const
- {
- return Vector2<T>(M[0][0] * b.x + M[0][1] * b.y,
- M[1][0] * b.x + M[1][1] * b.y);
- }
-
- Vector2<T> Transform(const Vector2<T>& v) const
- {
- return Vector2<T>(M[0][0] * v.x + M[0][1] * v.y,
- M[1][0] * v.x + M[1][1] * v.y);
- }
-
- Matrix2 Transposed() const
- {
- return Matrix2(M[0][0], M[1][0],
- M[0][1], M[1][1]);
- }
-
- void Transpose()
- {
- OVRMath_Swap(M[1][0], M[0][1]);
- }
-
- Vector2<T> GetColumn(int c) const
- {
- return Vector2<T>(M[0][c], M[1][c]);
- }
-
- Vector2<T> GetRow(int r) const
- {
- return Vector2<T>(M[r][0], M[r][1]);
- }
-
- void SetColumn(int c, const Vector2<T>& v)
- {
- M[0][c] = v.x;
- M[1][c] = v.y;
- }
-
- void SetRow(int r, const Vector2<T>& v)
- {
- M[r][0] = v.x;
- M[r][1] = v.y;
- }
-
- T Determinant() const
- {
- return M[0][0] * M[1][1] - M[0][1] * M[1][0];
- }
-
- Matrix2 Inverse() const
- {
- T rcpDet = T(1) / Determinant();
- return Matrix2( M[1][1] * rcpDet, -M[0][1] * rcpDet,
- -M[1][0] * rcpDet, M[0][0] * rcpDet);
- }
-
- // Outer Product of two column vectors: a * b.Transpose()
- static Matrix2 OuterProduct(const Vector2<T>& a, const Vector2<T>& b)
- {
- return Matrix2(a.x*b.x, a.x*b.y,
- a.y*b.x, a.y*b.y);
- }
-
- // Angle in radians between two rotation matrices
- T Angle(const Matrix2& b) const
- {
- const Matrix2& a = *this;
- return Acos(a(0, 0)*b(0, 0) + a(1, 0)*b(1, 0));
- }
-};
-
-typedef Matrix2<float> Matrix2f;
-typedef Matrix2<double> Matrix2d;
-
-//-------------------------------------------------------------------------------------
-
-template<class T>
-class SymMat3
-{
-private:
- typedef SymMat3<T> this_type;
-
-public:
- typedef T Value_t;
- // Upper symmetric
- T v[6]; // _00 _01 _02 _11 _12 _22
-
- inline SymMat3() {}
-
- inline explicit SymMat3(T s)
- {
- v[0] = v[3] = v[5] = s;
- v[1] = v[2] = v[4] = T(0);
- }
-
- inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22)
- {
- v[0] = a00; v[1] = a01; v[2] = a02;
- v[3] = a11; v[4] = a12;
- v[5] = a22;
- }
-
- // Cast to symmetric Matrix3
- operator Matrix3<T>() const
- {
- return Matrix3<T>(v[0], v[1], v[2],
- v[1], v[3], v[4],
- v[2], v[4], v[5]);
- }
-
- static inline int Index(unsigned int i, unsigned int j)
- {
- return (i <= j) ? (3*i - i*(i+1)/2 + j) : (3*j - j*(j+1)/2 + i);
- }
-
- inline T operator()(int i, int j) const { return v[Index(i,j)]; }
-
- inline T &operator()(int i, int j) { return v[Index(i,j)]; }
-
- inline this_type& operator+=(const this_type& b)
- {
- v[0]+=b.v[0];
- v[1]+=b.v[1];
- v[2]+=b.v[2];
- v[3]+=b.v[3];
- v[4]+=b.v[4];
- v[5]+=b.v[5];
- return *this;
- }
-
- inline this_type& operator-=(const this_type& b)
- {
- v[0]-=b.v[0];
- v[1]-=b.v[1];
- v[2]-=b.v[2];
- v[3]-=b.v[3];
- v[4]-=b.v[4];
- v[5]-=b.v[5];
-
- return *this;
- }
-
- inline this_type& operator*=(T s)
- {
- v[0]*=s;
- v[1]*=s;
- v[2]*=s;
- v[3]*=s;
- v[4]*=s;
- v[5]*=s;
-
- return *this;
- }
-
- inline SymMat3 operator*(T s) const
- {
- SymMat3 d;
- d.v[0] = v[0]*s;
- d.v[1] = v[1]*s;
- d.v[2] = v[2]*s;
- d.v[3] = v[3]*s;
- d.v[4] = v[4]*s;
- d.v[5] = v[5]*s;
-
- return d;
- }
-
- // Multiplies two matrices into destination with minimum copying.
- static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b)
- {
- // _00 _01 _02 _11 _12 _22
-
- d->v[0] = a.v[0] * b.v[0];
- d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3];
- d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4];
-
- d->v[3] = a.v[3] * b.v[3];
- d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5];
-
- d->v[5] = a.v[5] * b.v[5];
-
- return *d;
- }
-
- inline T Determinant() const
- {
- const this_type& m = *this;
- T d;
-
- d = m(0,0) * (m(1,1)*m(2,2) - m(1,2) * m(2,1));
- d -= m(0,1) * (m(1,0)*m(2,2) - m(1,2) * m(2,0));
- d += m(0,2) * (m(1,0)*m(2,1) - m(1,1) * m(2,0));
-
- return d;
- }
-
- inline this_type Inverse() const
- {
- this_type a;
- const this_type& m = *this;
- T d = Determinant();
-
- OVR_MATH_ASSERT(d != 0);
- T s = T(1)/d;
-
- a(0,0) = s * (m(1,1) * m(2,2) - m(1,2) * m(2,1));
-
- a(0,1) = s * (m(0,2) * m(2,1) - m(0,1) * m(2,2));
- a(1,1) = s * (m(0,0) * m(2,2) - m(0,2) * m(2,0));
-
- a(0,2) = s * (m(0,1) * m(1,2) - m(0,2) * m(1,1));
- a(1,2) = s * (m(0,2) * m(1,0) - m(0,0) * m(1,2));
- a(2,2) = s * (m(0,0) * m(1,1) - m(0,1) * m(1,0));
-
- return a;
- }
-
- inline T Trace() const { return v[0] + v[3] + v[5]; }
-
- // M = a*a.t()
- inline void Rank1(const Vector3<T> &a)
- {
- v[0] = a.x*a.x; v[1] = a.x*a.y; v[2] = a.x*a.z;
- v[3] = a.y*a.y; v[4] = a.y*a.z;
- v[5] = a.z*a.z;
- }
-
- // M += a*a.t()
- inline void Rank1Add(const Vector3<T> &a)
- {
- v[0] += a.x*a.x; v[1] += a.x*a.y; v[2] += a.x*a.z;
- v[3] += a.y*a.y; v[4] += a.y*a.z;
- v[5] += a.z*a.z;
- }
-
- // M -= a*a.t()
- inline void Rank1Sub(const Vector3<T> &a)
- {
- v[0] -= a.x*a.x; v[1] -= a.x*a.y; v[2] -= a.x*a.z;
- v[3] -= a.y*a.y; v[4] -= a.y*a.z;
- v[5] -= a.z*a.z;
- }
-};
-
-typedef SymMat3<float> SymMat3f;
-typedef SymMat3<double> SymMat3d;
-
-template<class T>
-inline Matrix3<T> operator*(const SymMat3<T>& a, const SymMat3<T>& b)
-{
- #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
- return Matrix3<T>(
- AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
- AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
- AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
- #undef AJB_ARBC
-}
-
-template<class T>
-inline Matrix3<T> operator*(const Matrix3<T>& a, const SymMat3<T>& b)
-{
- #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c))
- return Matrix3<T>(
- AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2),
- AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2),
- AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2));
- #undef AJB_ARBC
-}
-
-//-------------------------------------------------------------------------------------
-// ***** Angle
-
-// Cleanly representing the algebra of 2D rotations.
-// The operations maintain the angle between -Pi and Pi, the same range as atan2.
-
-template<class T>
-class Angle
-{
-public:
- enum AngularUnits
- {
- Radians = 0,
- Degrees = 1
- };
-
- Angle() : a(0) {}
-
- // Fix the range to be between -Pi and Pi
- Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); }
-
- T Get(AngularUnits u = Radians) const { return (u == Radians) ? a : a*((T)MATH_DOUBLE_RADTODEGREEFACTOR); }
- void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*((T)MATH_DOUBLE_DEGREETORADFACTOR); FixRange(); }
- int Sign() const { if (a == 0) return 0; else return (a > 0) ? 1 : -1; }
- T Abs() const { return (a >= 0) ? a : -a; }
-
- bool operator== (const Angle& b) const { return a == b.a; }
- bool operator!= (const Angle& b) const { return a != b.a; }
-// bool operator< (const Angle& b) const { return a < a.b; }
-// bool operator> (const Angle& b) const { return a > a.b; }
-// bool operator<= (const Angle& b) const { return a <= a.b; }
-// bool operator>= (const Angle& b) const { return a >= a.b; }
-// bool operator= (const T& x) { a = x; FixRange(); }
-
- // These operations assume a is already between -Pi and Pi.
- Angle& operator+= (const Angle& b) { a = a + b.a; FastFixRange(); return *this; }
- Angle& operator+= (const T& x) { a = a + x; FixRange(); return *this; }
- Angle operator+ (const Angle& b) const { Angle res = *this; res += b; return res; }
- Angle operator+ (const T& x) const { Angle res = *this; res += x; return res; }
- Angle& operator-= (const Angle& b) { a = a - b.a; FastFixRange(); return *this; }
- Angle& operator-= (const T& x) { a = a - x; FixRange(); return *this; }
- Angle operator- (const Angle& b) const { Angle res = *this; res -= b; return res; }
- Angle operator- (const T& x) const { Angle res = *this; res -= x; return res; }
-
- T Distance(const Angle& b) { T c = fabs(a - b.a); return (c <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_TWOPI) - c; }
-
-private:
-
- // The stored angle, which should be maintained between -Pi and Pi
- T a;
-
- // Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side
- inline void FastFixRange()
- {
- if (a < -((T)MATH_DOUBLE_PI))
- a += ((T)MATH_DOUBLE_TWOPI);
- else if (a > ((T)MATH_DOUBLE_PI))
- a -= ((T)MATH_DOUBLE_TWOPI);
- }
-
- // Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method
- inline void FixRange()
- {
- // do nothing if the value is already in the correct range, since fmod call is expensive
- if (a >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI))
- return;
- a = fmod(a,((T)MATH_DOUBLE_TWOPI));
- if (a < -((T)MATH_DOUBLE_PI))
- a += ((T)MATH_DOUBLE_TWOPI);
- else if (a > ((T)MATH_DOUBLE_PI))
- a -= ((T)MATH_DOUBLE_TWOPI);
- }
-};
-
-
-typedef Angle<float> Anglef;
-typedef Angle<double> Angled;
-
-
-//-------------------------------------------------------------------------------------
-// ***** Plane
-
-// Consists of a normal vector and distance from the origin where the plane is located.
-
-template<class T>
-class Plane
-{
-public:
- Vector3<T> N;
- T D;
-
- Plane() : D(0) {}
-
- // Normals must already be normalized
- Plane(const Vector3<T>& n, T d) : N(n), D(d) {}
- Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {}
-
- // construct from a point on the plane and the normal
- Plane(const Vector3<T>& p, const Vector3<T>& n) : N(n), D(-(p * n)) {}
-
- // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane).
- T TestSide(const Vector3<T>& p) const
- {
- return (N.Dot(p)) + D;
- }
-
- Plane<T> Flipped() const
- {
- return Plane(-N, -D);
- }
-
- void Flip()
- {
- N = -N;
- D = -D;
- }
-
- bool operator==(const Plane<T>& rhs) const
- {
- return (this->D == rhs.D && this->N == rhs.N);
- }
-};
-
-typedef Plane<float> Planef;
-typedef Plane<double> Planed;
-
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** ScaleAndOffset2D
-
-struct ScaleAndOffset2D
-{
- Vector2f Scale;
- Vector2f Offset;
-
- ScaleAndOffset2D(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f)
- : Scale(sx, sy), Offset(ox, oy)
- { }
-};
-
-
-//-----------------------------------------------------------------------------------
-// ***** FovPort
-
-// FovPort describes Field Of View (FOV) of a viewport.
-// This class has values for up, down, left and right, stored in
-// tangent of the angle units to simplify calculations.
-//
-// As an example, for a standard 90 degree vertical FOV, we would
-// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
-//
-// CreateFromRadians/Degrees helper functions can be used to
-// access FOV in different units.
-
-
-// ***** FovPort
-
-struct FovPort
-{
- float UpTan;
- float DownTan;
- float LeftTan;
- float RightTan;
-
- FovPort ( float sideTan = 0.0f ) :
- UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) { }
- FovPort ( float u, float d, float l, float r ) :
- UpTan(u), DownTan(d), LeftTan(l), RightTan(r) { }
-
- // C-interop support: FovPort <-> ovrFovPort (implementation in OVR_CAPI.cpp).
- FovPort(const ovrFovPort &src)
- : UpTan(src.UpTan), DownTan(src.DownTan), LeftTan(src.LeftTan), RightTan(src.RightTan)
- { }
-
- operator ovrFovPort () const
- {
- ovrFovPort result;
- result.LeftTan = LeftTan;
- result.RightTan = RightTan;
- result.UpTan = UpTan;
- result.DownTan = DownTan;
- return result;
- }
-
- static FovPort CreateFromRadians(float horizontalFov, float verticalFov)
- {
- FovPort result;
- result.UpTan = tanf ( verticalFov * 0.5f );
- result.DownTan = tanf ( verticalFov * 0.5f );
- result.LeftTan = tanf ( horizontalFov * 0.5f );
- result.RightTan = tanf ( horizontalFov * 0.5f );
- return result;
- }
-
- static FovPort CreateFromDegrees(float horizontalFovDegrees,
- float verticalFovDegrees)
- {
- return CreateFromRadians(DegreeToRad(horizontalFovDegrees),
- DegreeToRad(verticalFovDegrees));
- }
-
- // Get Horizontal/Vertical components of Fov in radians.
- float GetVerticalFovRadians() const { return atanf(UpTan) + atanf(DownTan); }
- float GetHorizontalFovRadians() const { return atanf(LeftTan) + atanf(RightTan); }
- // Get Horizontal/Vertical components of Fov in degrees.
- float GetVerticalFovDegrees() const { return RadToDegree(GetVerticalFovRadians()); }
- float GetHorizontalFovDegrees() const { return RadToDegree(GetHorizontalFovRadians()); }
-
- // Compute maximum tangent value among all four sides.
- float GetMaxSideTan() const
- {
- return OVRMath_Max(OVRMath_Max(UpTan, DownTan), OVRMath_Max(LeftTan, RightTan));
- }
-
- static ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort tanHalfFov )
- {
- float projXScale = 2.0f / ( tanHalfFov.LeftTan + tanHalfFov.RightTan );
- float projXOffset = ( tanHalfFov.LeftTan - tanHalfFov.RightTan ) * projXScale * 0.5f;
- float projYScale = 2.0f / ( tanHalfFov.UpTan + tanHalfFov.DownTan );
- float projYOffset = ( tanHalfFov.UpTan - tanHalfFov.DownTan ) * projYScale * 0.5f;
-
- ScaleAndOffset2D result;
- result.Scale = Vector2f(projXScale, projYScale);
- result.Offset = Vector2f(projXOffset, projYOffset);
- // Hey - why is that Y.Offset negated?
- // It's because a projection matrix transforms from world coords with Y=up,
- // whereas this is from NDC which is Y=down.
-
- return result;
- }
-
- // Converts Fov Tan angle units to [-1,1] render target NDC space
- Vector2f TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle)
- {
- ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(*this);
- return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset;
- }
-
- // Compute per-channel minimum and maximum of Fov.
- static FovPort Min(const FovPort& a, const FovPort& b)
- {
- FovPort fov( OVRMath_Min( a.UpTan , b.UpTan ),
- OVRMath_Min( a.DownTan , b.DownTan ),
- OVRMath_Min( a.LeftTan , b.LeftTan ),
- OVRMath_Min( a.RightTan, b.RightTan ) );
- return fov;
- }
-
- static FovPort Max(const FovPort& a, const FovPort& b)
- {
- FovPort fov( OVRMath_Max( a.UpTan , b.UpTan ),
- OVRMath_Max( a.DownTan , b.DownTan ),
- OVRMath_Max( a.LeftTan , b.LeftTan ),
- OVRMath_Max( a.RightTan, b.RightTan ) );
- return fov;
- }
-};
-
-
-} // Namespace OVR
-
-
-#if defined(_MSC_VER)
- #pragma warning(pop)
-#endif
-
-
-#endif
diff --git a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_StereoProjection.h b/src/external/OculusSDK/LibOVR/Include/Extras/OVR_StereoProjection.h
deleted file mode 100644
index b4bc3bc7..00000000
--- a/src/external/OculusSDK/LibOVR/Include/Extras/OVR_StereoProjection.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/************************************************************************************
-
-Filename : OVR_StereoProjection.h
-Content : Stereo projection functions
-Created : November 30, 2013
-Authors : Tom Fosyth
-
-Copyright : Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
-
-Licensed under the Oculus VR Rift SDK License Version 3.3 (the "License");
-you may not use the Oculus VR Rift SDK except in compliance with the License,
-which is provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-You may obtain a copy of the License at
-
-http://www.oculusvr.com/licenses/LICENSE-3.3
-
-Unless required by applicable law or agreed to in writing, the Oculus VR SDK
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-*************************************************************************************/
-
-#ifndef OVR_StereoProjection_h
-#define OVR_StereoProjection_h
-
-
-#include "Extras/OVR_Math.h"
-
-
-namespace OVR {
-
-
-//-----------------------------------------------------------------------------------
-// ***** Stereo Enumerations
-
-// StereoEye specifies which eye we are rendering for; it is used to
-// retrieve StereoEyeParams.
-enum StereoEye
-{
- StereoEye_Left,
- StereoEye_Right,
- StereoEye_Center
-};
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** Propjection functions
-
-Matrix4f CreateProjection ( bool rightHanded, bool isOpenGL, FovPort fov, StereoEye eye,
- float zNear = 0.01f, float zFar = 10000.0f,
- bool flipZ = false, bool farAtInfinity = false);
-
-Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType,
- float tanHalfFovX, float tanHalfFovY,
- float unitsX, float unitsY, float distanceFromCamera,
- float interpupillaryDistance, Matrix4f const &projection,
- float zNear = 0.0f, float zFar = 0.0f,
- bool flipZ = false, bool farAtInfinity = false);
-
-ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort fov );
-
-
-} //namespace OVR
-
-#endif // OVR_StereoProjection_h
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h
deleted file mode 100644
index eaabcf59..00000000
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI.h
+++ /dev/null
@@ -1,2234 +0,0 @@
-/********************************************************************************//**
-\file OVR_CAPI.h
-\brief C Interface to the Oculus PC SDK tracking and rendering library.
-\copyright Copyright 2014 Oculus VR, LLC All Rights reserved.
-************************************************************************************/
-
-#ifndef OVR_CAPI_h // We don't use version numbers within this name, as all versioned variations of this file are currently mutually exclusive.
-#define OVR_CAPI_h ///< Header include guard
-
-
-#include "OVR_CAPI_Keys.h"
-#include "OVR_Version.h"
-#include "OVR_ErrorCode.h"
-
-
-#include <stdint.h>
-
-#if defined(_MSC_VER)
- #pragma warning(push)
- #pragma warning(disable: 4324) // structure was padded due to __declspec(align())
- #pragma warning(disable: 4359) // The alignment specified for a type is less than the alignment of the type of one of its data members
-#endif
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_OS
-//
-#if !defined(OVR_OS_WIN32) && defined(_WIN32)
- #define OVR_OS_WIN32
-#endif
-
-#if !defined(OVR_OS_MAC) && defined(__APPLE__)
- #define OVR_OS_MAC
-#endif
-
-#if !defined(OVR_OS_LINUX) && defined(__linux__)
- #define OVR_OS_LINUX
-#endif
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_CPP
-//
-#if !defined(OVR_CPP)
- #if defined(__cplusplus)
- #define OVR_CPP(x) x
- #else
- #define OVR_CPP(x) /* Not C++ */
- #endif
-#endif
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_CDECL
-//
-/// LibOVR calling convention for 32-bit Windows builds.
-//
-#if !defined(OVR_CDECL)
- #if defined(_WIN32)
- #define OVR_CDECL __cdecl
- #else
- #define OVR_CDECL
- #endif
-#endif
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_EXTERN_C
-//
-/// Defined as extern "C" when built from C++ code.
-//
-#if !defined(OVR_EXTERN_C)
- #ifdef __cplusplus
- #define OVR_EXTERN_C extern "C"
- #else
- #define OVR_EXTERN_C
- #endif
-#endif
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_PUBLIC_FUNCTION / OVR_PRIVATE_FUNCTION
-//
-// OVR_PUBLIC_FUNCTION - Functions that externally visible from a shared library. Corresponds to Microsoft __dllexport.
-// OVR_PUBLIC_CLASS - C++ structs and classes that are externally visible from a shared library. Corresponds to Microsoft __dllexport.
-// OVR_PRIVATE_FUNCTION - Functions that are not visible outside of a shared library. They are private to the shared library.
-// OVR_PRIVATE_CLASS - C++ structs and classes that are not visible outside of a shared library. They are private to the shared library.
-//
-// OVR_DLL_BUILD - Used to indicate that the current compilation unit is of a shared library.
-// OVR_DLL_IMPORT - Used to indicate that the current compilation unit is a user of the corresponding shared library.
-// OVR_STATIC_BUILD - used to indicate that the current compilation unit is not a shared library but rather statically linked code.
-//
-#if !defined(OVR_PUBLIC_FUNCTION)
- #if defined(OVR_DLL_BUILD)
- #if defined(_WIN32)
- #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllexport) rval OVR_CDECL
- #define OVR_PUBLIC_CLASS __declspec(dllexport)
- #define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL
- #define OVR_PRIVATE_CLASS
- #else
- #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __attribute__((visibility("default"))) rval OVR_CDECL /* Requires GCC 4.0+ */
- #define OVR_PUBLIC_CLASS __attribute__((visibility("default"))) /* Requires GCC 4.0+ */
- #define OVR_PRIVATE_FUNCTION(rval) __attribute__((visibility("hidden"))) rval OVR_CDECL
- #define OVR_PRIVATE_CLASS __attribute__((visibility("hidden")))
- #endif
- #elif defined(OVR_DLL_IMPORT)
- #if defined(_WIN32)
- #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllimport) rval OVR_CDECL
- #define OVR_PUBLIC_CLASS __declspec(dllimport)
- #else
- #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL
- #define OVR_PUBLIC_CLASS
- #endif
- #define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL
- #define OVR_PRIVATE_CLASS
- #else // OVR_STATIC_BUILD
- #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL
- #define OVR_PUBLIC_CLASS
- #define OVR_PRIVATE_FUNCTION(rval) rval OVR_CDECL
- #define OVR_PRIVATE_CLASS
- #endif
-#endif
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_EXPORT
-//
-/// Provided for backward compatibility with older versions of this library.
-//
-#if !defined(OVR_EXPORT)
- #ifdef OVR_OS_WIN32
- #define OVR_EXPORT __declspec(dllexport)
- #else
- #define OVR_EXPORT
- #endif
-#endif
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_ALIGNAS
-//
-#if !defined(OVR_ALIGNAS)
- #if defined(__GNUC__) || defined(__clang__)
- #define OVR_ALIGNAS(n) __attribute__((aligned(n)))
- #elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
- #define OVR_ALIGNAS(n) __declspec(align(n))
- #elif defined(__CC_ARM)
- #define OVR_ALIGNAS(n) __align(n)
- #else
- #error Need to define OVR_ALIGNAS
- #endif
-#endif
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_CC_HAS_FEATURE
-//
-// This is a portable way to use compile-time feature identification available
-// with some compilers in a clean way. Direct usage of __has_feature in preprocessing
-// statements of non-supporting compilers results in a preprocessing error.
-//
-// Example usage:
-// #if OVR_CC_HAS_FEATURE(is_pod)
-// if(__is_pod(T)) // If the type is plain data then we can safely memcpy it.
-// memcpy(&destObject, &srcObject, sizeof(object));
-// #endif
-//
-#if !defined(OVR_CC_HAS_FEATURE)
- #if defined(__clang__) // http://clang.llvm.org/docs/LanguageExtensions.html#id2
- #define OVR_CC_HAS_FEATURE(x) __has_feature(x)
- #else
- #define OVR_CC_HAS_FEATURE(x) 0
- #endif
-#endif
-
-
-// ------------------------------------------------------------------------
-// ***** OVR_STATIC_ASSERT
-//
-// Portable support for C++11 static_assert().
-// Acts as if the following were declared:
-// void OVR_STATIC_ASSERT(bool const_expression, const char* msg);
-//
-// Example usage:
-// OVR_STATIC_ASSERT(sizeof(int32_t) == 4, "int32_t expected to be 4 bytes.");
-
-#if !defined(OVR_STATIC_ASSERT)
- #if !(defined(__cplusplus) && (__cplusplus >= 201103L)) /* Other */ && \
- !(defined(__GXX_EXPERIMENTAL_CXX0X__)) /* GCC */ && \
- !(defined(__clang__) && defined(__cplusplus) && OVR_CC_HAS_FEATURE(cxx_static_assert)) /* clang */ && \
- !(defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus)) /* VS2010+ */
-
- #if !defined(OVR_SA_UNUSED)
- #if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG)
- #define OVR_SA_UNUSED __attribute__((unused))
- #else
- #define OVR_SA_UNUSED
- #endif
- #define OVR_SA_PASTE(a,b) a##b
- #define OVR_SA_HELP(a,b) OVR_SA_PASTE(a,b)
- #endif
-
- #if defined(__COUNTER__)
- #define OVR_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __COUNTER__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED
- #else
- #define OVR_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED
- #endif
-
- #else
- #define OVR_STATIC_ASSERT(expression, msg) static_assert(expression, msg)
- #endif
-#endif
-
-
-//-----------------------------------------------------------------------------------
-// ***** Padding
-//
-/// Defines explicitly unused space for a struct.
-/// When used correcly, usage of this macro should not change the size of the struct.
-/// Compile-time and runtime behavior with and without this defined should be identical.
-///
-#if !defined(OVR_UNUSED_STRUCT_PAD)
- #define OVR_UNUSED_STRUCT_PAD(padName, size) char padName[size];
-#endif
-
-
-//-----------------------------------------------------------------------------------
-// ***** Word Size
-//
-/// Specifies the size of a pointer on the given platform.
-///
-#if !defined(OVR_PTR_SIZE)
- #if defined(__WORDSIZE)
- #define OVR_PTR_SIZE ((__WORDSIZE) / 8)
- #elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__64BIT__) || defined(__Ptr_Is_64)
- #define OVR_PTR_SIZE 8
- #elif defined(__CC_ARM) && (__sizeof_ptr == 8)
- #define OVR_PTR_SIZE 8
- #else
- #define OVR_PTR_SIZE 4
- #endif
-#endif
-
-
-//-----------------------------------------------------------------------------------
-// ***** OVR_ON32 / OVR_ON64
-//
-#if OVR_PTR_SIZE == 8
- #define OVR_ON32(x)
- #define OVR_ON64(x) x
-#else
- #define OVR_ON32(x) x
- #define OVR_ON64(x)
-#endif
-
-
-//-----------------------------------------------------------------------------------
-// ***** ovrBool
-
-typedef char ovrBool; ///< Boolean type
-#define ovrFalse 0 ///< ovrBool value of false.
-#define ovrTrue 1 ///< ovrBool value of true.
-
-
-//-----------------------------------------------------------------------------------
-// ***** 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_
-{
- int x, y;
-} ovrVector2i;
-
-/// A 2D size with integer components.
-typedef struct OVR_ALIGNAS(4) ovrSizei_
-{
- int w, h;
-} ovrSizei;
-
-/// A 2D rectangle with a position and size.
-/// All components are integers.
-typedef struct OVR_ALIGNAS(4) ovrRecti_
-{
- ovrVector2i Pos;
- ovrSizei Size;
-} ovrRecti;
-
-/// A quaternion rotation.
-typedef struct OVR_ALIGNAS(4) ovrQuatf_
-{
- float x, y, z, w;
-} ovrQuatf;
-
-/// A 2D vector with float components.
-typedef struct OVR_ALIGNAS(4) ovrVector2f_
-{
- float x, y;
-} ovrVector2f;
-
-/// A 3D vector with float components.
-typedef struct OVR_ALIGNAS(4) ovrVector3f_
-{
- float x, y, z;
-} ovrVector3f;
-
-/// A 4x4 matrix with float elements.
-typedef struct OVR_ALIGNAS(4) ovrMatrix4f_
-{
- float M[4][4];
-} ovrMatrix4f;
-
-
-/// Position and orientation together.
-typedef struct OVR_ALIGNAS(4) ovrPosef_
-{
- ovrQuatf Orientation;
- ovrVector3f Position;
-} 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
-/// depends on the usage of the struct.
-typedef struct OVR_ALIGNAS(8) ovrPoseStatef_
-{
- ovrPosef ThePose; ///< Position and orientation.
- ovrVector3f AngularVelocity; ///< Angular velocity in radians per second.
- ovrVector3f LinearVelocity; ///< Velocity in meters per second.
- ovrVector3f AngularAcceleration; ///< Angular acceleration in radians per second per second.
- ovrVector3f LinearAcceleration; ///< Acceleration in meters per second per second.
- OVR_UNUSED_STRUCT_PAD(pad0, 4) ///< \internal struct pad.
- double TimeInSeconds; ///< Absolute time that this pose refers to. \see ovr_GetTimeInSeconds
-} ovrPoseStatef;
-
-/// Describes the up, down, left, and right angles of the field of view.
-///
-/// Field Of View (FOV) tangent of the angle units.
-/// \note For a standard 90 degree vertical FOV, we would
-/// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }.
-typedef struct OVR_ALIGNAS(4) ovrFovPort_
-{
- float UpTan; ///< The tangent of the angle between the viewing vector and the top edge of the field of view.
- float DownTan; ///< The tangent of the angle between the viewing vector and the bottom edge of the field of view.
- float LeftTan; ///< The tangent of the angle between the viewing vector and the left edge of the field of view.
- float RightTan; ///< The tangent of the angle between the viewing vector and the right edge of the field of view.
-} ovrFovPort;
-
-
-//-----------------------------------------------------------------------------------
-// ***** HMD Types
-
-/// Enumerates all HMD types that we support.
-///
-/// The currently released developer kits are ovrHmd_DK1 and ovrHmd_DK2. The other enumerations are for internal use only.
-typedef enum ovrHmdType_
-{
- ovrHmd_None = 0,
- ovrHmd_DK1 = 3,
- ovrHmd_DKHD = 4,
- ovrHmd_DK2 = 6,
- ovrHmd_CB = 8,
- ovrHmd_Other = 9,
- ovrHmd_E3_2015 = 10,
- ovrHmd_ES06 = 11,
- ovrHmd_ES09 = 12,
- ovrHmd_ES11 = 13,
- ovrHmd_CV1 = 14,
-
- ovrHmd_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrHmdType;
-
-
-/// HMD capability bits reported by device.
-///
-typedef enum ovrHmdCaps_
-{
- // Read-only flags
- ovrHmdCap_DebugDevice = 0x0010, ///< <B>(read only)</B> Specifies that the HMD is a virtual debug device.
-
-
- ovrHmdCap_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrHmdCaps;
-
-
-/// Tracking capability bits reported by the device.
-/// Used with ovr_GetTrackingCaps.
-typedef enum ovrTrackingCaps_
-{
- ovrTrackingCap_Orientation = 0x0010, ///< Supports orientation tracking (IMU).
- ovrTrackingCap_MagYawCorrection = 0x0020, ///< Supports yaw drift correction via a magnetometer or other means.
- ovrTrackingCap_Position = 0x0040, ///< Supports positional tracking.
- ovrTrackingCap_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrTrackingCaps;
-
-
-/// Specifies which eye is being used for rendering.
-/// This type explicitly does not include a third "NoStereo" monoscopic option, as such is
-/// not required for an HMD-centered API.
-typedef enum ovrEyeType_
-{
- ovrEye_Left = 0, ///< The left eye, from the viewer's perspective.
- ovrEye_Right = 1, ///< The right eye, from the viewer's perspective.
- ovrEye_Count = 2, ///< \internal Count of enumerated elements.
- ovrEye_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrEyeType;
-
-/// Specifies the coordinate system ovrTrackingState returns tracking poses in.
-/// Used with ovr_SetTrackingOriginType()
-typedef enum ovrTrackingOrigin_
-{
- /// \brief Tracking system origin reported at eye (HMD) height
- /// \details Prefer using this origin when your application requires
- /// matching user's current physical head pose to a virtual head pose
- /// without any regards to a the height of the floor. Cockpit-based,
- /// or 3rd-person experiences are ideal candidates.
- /// When used, all poses in ovrTrackingState are reported as an offset
- /// transform from the profile calibrated or recentered HMD pose.
- /// It is recommended that apps using this origin type call ovr_RecenterTrackingOrigin
- /// prior to starting the VR experience, but notify the user before doing so
- /// to make sure the user is in a comfortable pose, facing a comfortable
- /// direction.
- ovrTrackingOrigin_EyeLevel = 0,
- /// \brief Tracking system origin reported at floor height
- /// \details Prefer using this origin when your application requires the
- /// physical floor height to match the virtual floor height, such as
- /// standing experiences.
- /// When used, all poses in ovrTrackingState are reported as an offset
- /// transform from the profile calibrated floor pose. Calling ovr_RecenterTrackingOrigin
- /// will recenter the X & Z axes as well as yaw, but the Y-axis (i.e. height) will continue
- /// to be reported using the floor height as the origin for all poses.
- ovrTrackingOrigin_FloorLevel = 1,
- ovrTrackingOrigin_Count = 2, ///< \internal Count of enumerated elements.
- ovrTrackingOrigin_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrTrackingOrigin;
-
-/// Identifies a graphics device in a platform-specific way.
-/// For Windows this is a LUID type.
-typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrGraphicsLuid_
-{
- // Public definition reserves space for graphics API-specific implementation
- char Reserved[8];
-} ovrGraphicsLuid;
-
-
-/// This is a complete descriptor of the HMD.
-typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrHmdDesc_
-{
- ovrHmdType Type; ///< The type of HMD.
- OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad0, 4)) ///< \internal struct paddding.
- char ProductName[64]; ///< UTF8-encoded product identification string (e.g. "Oculus Rift DK1").
- char Manufacturer[64]; ///< UTF8-encoded HMD manufacturer identification string.
- short VendorId; ///< HID (USB) vendor identifier of the device.
- short ProductId; ///< HID (USB) product identifier of the device.
- char SerialNumber[24]; ///< HMD serial number.
- short FirmwareMajor; ///< HMD firmware major version.
- short FirmwareMinor; ///< HMD firmware minor version.
- unsigned int AvailableHmdCaps; ///< Capability bits described by ovrHmdCaps which the HMD currently supports.
- unsigned int DefaultHmdCaps; ///< Capability bits described by ovrHmdCaps which are default for the current Hmd.
- unsigned int AvailableTrackingCaps; ///< Capability bits described by ovrTrackingCaps which the system currently supports.
- unsigned int DefaultTrackingCaps; ///< Capability bits described by ovrTrackingCaps which are default for the current system.
- ovrFovPort DefaultEyeFov[ovrEye_Count]; ///< Defines the recommended FOVs for the HMD.
- ovrFovPort MaxEyeFov[ovrEye_Count]; ///< Defines the maximum FOVs for the HMD.
- ovrSizei Resolution; ///< Resolution of the full HMD screen (both eyes) in pixels.
- float DisplayRefreshRate; ///< Nominal refresh rate of the display in cycles per second at the time of HMD creation.
- OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad1, 4)) ///< \internal struct paddding.
-} ovrHmdDesc;
-
-
-/// Used as an opaque pointer to an OVR session.
-typedef struct ovrHmdStruct* ovrSession;
-
-
-
-/// Bit flags describing the current status of sensor tracking.
-/// The values must be the same as in enum StatusBits
-///
-/// \see ovrTrackingState
-///
-typedef enum ovrStatusBits_
-{
- ovrStatus_OrientationTracked = 0x0001, ///< Orientation is currently tracked (connected and in use).
- ovrStatus_PositionTracked = 0x0002, ///< Position is currently tracked (false if out of range).
- ovrStatus_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrStatusBits;
-
-
-/// Specifies the description of a single sensor.
-///
-/// \see ovr_GetTrackerDesc
-///
-typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrTrackerDesc_
-{
- float FrustumHFovInRadians; ///< Sensor frustum horizontal field-of-view (if present).
- float FrustumVFovInRadians; ///< Sensor frustum vertical field-of-view (if present).
- float FrustumNearZInMeters; ///< Sensor frustum near Z (if present).
- float FrustumFarZInMeters; ///< Sensor frustum far Z (if present).
-} ovrTrackerDesc;
-
-
-/// Specifies sensor flags.
-///
-/// /see ovrTrackerPose
-///
-typedef enum ovrTrackerFlags_
-{
- ovrTracker_Connected = 0x0020, ///< The sensor is present, else the sensor is absent or offline.
- ovrTracker_PoseTracked = 0x0004 ///< The sensor has a valid pose, else the pose is unavailable. This will only be set if ovrTracker_Connected is set.
-} ovrTrackerFlags;
-
-
-/// Specifies the pose for a single sensor.
-///
-typedef struct OVR_ALIGNAS(8) _ovrTrackerPose
-{
- unsigned int TrackerFlags; ///< ovrTrackerFlags.
- ovrPosef Pose; ///< The sensor's pose. This pose includes sensor tilt (roll and pitch). For a leveled coordinate system use LeveledPose.
- ovrPosef LeveledPose; ///< The sensor's leveled pose, aligned with gravity. This value includes position and yaw of the sensor, but not roll and pitch. It can be used as a reference point to render real-world objects in the correct location.
- OVR_UNUSED_STRUCT_PAD(pad0, 4) ///< \internal struct pad.
-} ovrTrackerPose;
-
-
-/// Tracking state at a given absolute time (describes predicted HMD pose, etc.).
-/// Returned by ovr_GetTrackingState.
-///
-/// \see ovr_GetTrackingState
-///
-typedef struct OVR_ALIGNAS(8) ovrTrackingState_
-{
- /// Predicted head pose (and derivatives) at the requested absolute time.
- ovrPoseStatef HeadPose;
-
- /// HeadPose tracking status described by ovrStatusBits.
- unsigned int StatusFlags;
-
- /// The most recent calculated pose for each hand when hand controller tracking is present.
- /// HandPoses[ovrHand_Left] refers to the left hand and HandPoses[ovrHand_Right] to the right hand.
- /// These values can be combined with ovrInputState for complete hand controller information.
- ovrPoseStatef HandPoses[2];
-
- /// HandPoses status flags described by ovrStatusBits.
- /// Only ovrStatus_OrientationTracked and ovrStatus_PositionTracked are reported.
- unsigned int HandStatusFlags[2];
-
- /// The pose of the origin captured during calibration.
- /// Like all other poses here, this is expressed in the space set by ovr_RecenterTrackingOrigin,
- /// and so will change every time that is called. This pose can be used to calculate
- /// where the calibrated origin lands in the new recentered space.
- /// If an application never calls ovr_RecenterTrackingOrigin, expect this value to be the identity
- /// pose and as such will point respective origin based on ovrTrackingOrigin requested when
- /// calling ovr_GetTrackingState.
- ovrPosef CalibratedOrigin;
-
-} ovrTrackingState;
-
-
-/// Rendering information for each eye. Computed by ovr_GetRenderDesc() based on the
-/// specified FOV. Note that the rendering viewport is not included
-/// here as it can be specified separately and modified per frame by
-/// passing different Viewport values in the layer structure.
-///
-/// \see ovr_GetRenderDesc
-///
-typedef struct OVR_ALIGNAS(4) ovrEyeRenderDesc_
-{
- ovrEyeType Eye; ///< The eye index to which this instance corresponds.
- ovrFovPort Fov; ///< The field of view.
- ovrRecti DistortedViewport; ///< Distortion viewport.
- ovrVector2f PixelsPerTanAngleAtCenter; ///< How many display pixels will fit in tan(angle) = 1.
- ovrVector3f HmdToEyeOffset; ///< Translation of each eye, in meters.
-} ovrEyeRenderDesc;
-
-
-/// Projection information for ovrLayerEyeFovDepth.
-///
-/// Use the utility function ovrTimewarpProjectionDesc_FromProjection to
-/// generate this structure from the application's projection matrix.
-///
-/// \see ovrLayerEyeFovDepth, ovrTimewarpProjectionDesc_FromProjection
-///
-typedef struct OVR_ALIGNAS(4) ovrTimewarpProjectionDesc_
-{
- float Projection22; ///< Projection matrix element [2][2].
- float Projection23; ///< Projection matrix element [2][3].
- float Projection32; ///< Projection matrix element [3][2].
-} ovrTimewarpProjectionDesc;
-
-
-/// Contains the data necessary to properly calculate position info for various layer types.
-/// - HmdToEyeOffset is the same value pair provided in ovrEyeRenderDesc.
-/// - HmdSpaceToWorldScaleInMeters is used to scale player motion into in-application units.
-/// In other words, it is how big an in-application unit is in the player's physical meters.
-/// For example, if the application uses inches as its units then HmdSpaceToWorldScaleInMeters would be 0.0254.
-/// Note that if you are scaling the player in size, this must also scale. So if your application
-/// units are inches, but you're shrinking the player to half their normal size, then
-/// HmdSpaceToWorldScaleInMeters would be 0.0254*2.0.
-///
-/// \see ovrEyeRenderDesc, ovr_SubmitFrame
-///
-typedef struct OVR_ALIGNAS(4) ovrViewScaleDesc_
-{
- ovrVector3f HmdToEyeOffset[ovrEye_Count]; ///< Translation of each eye.
- float HmdSpaceToWorldScaleInMeters; ///< Ratio of viewer units to meter units.
-} ovrViewScaleDesc;
-
-
-//-----------------------------------------------------------------------------------
-// ***** Platform-independent Rendering Configuration
-
-/// The type of texture resource.
-///
-/// \see ovrTextureSwapChainDesc
-///
-typedef enum ovrTextureType_
-{
- ovrTexture_2D, ///< 2D textures.
- ovrTexture_2D_External, ///< External 2D texture. Not used on PC
- ovrTexture_Cube, ///< Cube maps. Not currently supported on PC.
- ovrTexture_Count,
- ovrTexture_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrTextureType;
-
-/// The bindings required for texture swap chain.
-///
-/// All texture swap chains are automatically bindable as shader
-/// input resources since the Oculus runtime needs this to read them.
-///
-/// \see ovrTextureSwapChainDesc
-///
-typedef enum ovrTextureBindFlags_
-{
- ovrTextureBind_None,
- ovrTextureBind_DX_RenderTarget = 0x0001, ///< The application can write into the chain with pixel shader
- ovrTextureBind_DX_UnorderedAccess = 0x0002, ///< The application can write to the chain with compute shader
- ovrTextureBind_DX_DepthStencil = 0x0004, ///< The chain buffers can be bound as depth and/or stencil buffers
-
- ovrTextureBind_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrTextureBindFlags;
-
-/// The format of a texture.
-///
-/// \see ovrTextureSwapChainDesc
-///
-typedef enum ovrTextureFormat_
-{
- OVR_FORMAT_UNKNOWN,
- OVR_FORMAT_B5G6R5_UNORM, ///< Not currently supported on PC. Would require a DirectX 11.1 device.
- OVR_FORMAT_B5G5R5A1_UNORM, ///< Not currently supported on PC. Would require a DirectX 11.1 device.
- OVR_FORMAT_B4G4R4A4_UNORM, ///< Not currently supported on PC. Would require a DirectX 11.1 device.
- OVR_FORMAT_R8G8B8A8_UNORM,
- OVR_FORMAT_R8G8B8A8_UNORM_SRGB,
- OVR_FORMAT_B8G8R8A8_UNORM,
- OVR_FORMAT_B8G8R8A8_UNORM_SRGB, ///< Not supported for OpenGL applications
- OVR_FORMAT_B8G8R8X8_UNORM, ///< Not supported for OpenGL applications
- OVR_FORMAT_B8G8R8X8_UNORM_SRGB, ///< Not supported for OpenGL applications
- OVR_FORMAT_R16G16B16A16_FLOAT,
- OVR_FORMAT_D16_UNORM,
- OVR_FORMAT_D24_UNORM_S8_UINT,
- OVR_FORMAT_D32_FLOAT,
- OVR_FORMAT_D32_FLOAT_S8X24_UINT,
-
- // Added in 1.5 compressed formats can be used for static layers
- OVR_FORMAT_BC1_UNORM,
- OVR_FORMAT_BC1_UNORM_SRGB,
- OVR_FORMAT_BC2_UNORM,
- OVR_FORMAT_BC2_UNORM_SRGB,
- OVR_FORMAT_BC3_UNORM,
- OVR_FORMAT_BC3_UNORM_SRGB,
- OVR_FORMAT_BC6H_UF16,
- OVR_FORMAT_BC6H_SF16,
- OVR_FORMAT_BC7_UNORM,
- OVR_FORMAT_BC7_UNORM_SRGB,
-
- OVR_FORMAT_ENUMSIZE = 0x7fffffff ///< \internal Force type int32_t.
-} ovrTextureFormat;
-
-/// Misc flags overriding particular
-/// behaviors of a texture swap chain
-///
-/// \see ovrTextureSwapChainDesc
-///
-typedef enum ovrTextureMiscFlags_
-{
- 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
- /// texture using the format specified in the texture desc, but the app can
- /// create views with different formats if this is specified.
- ovrTextureMisc_DX_Typeless = 0x0001,
-
- /// DX only: Allow generation of the mip chain on the GPU via the GenerateMips
- /// call. This flag requires that RenderTarget binding also be specified.
- ovrTextureMisc_AllowGenerateMips = 0x0002,
-
- /// Texture swap chain contains protected content, and requires
- /// HDCP connection in order to display to HMD. Also prevents
- /// mirroring or other redirection of any frame containing this contents
- ovrTextureMisc_ProtectedContent = 0x0004,
-
- ovrTextureMisc_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrTextureFlags;
-
-/// Description used to create a texture swap chain.
-///
-/// \see ovr_CreateTextureSwapChainDX
-/// \see ovr_CreateTextureSwapChainGL
-///
-typedef struct ovrTextureSwapChainDesc_
-{
- ovrTextureType Type;
- ovrTextureFormat Format;
- int ArraySize; ///< Only supported with ovrTexture_2D. Not supported on PC at this time.
- int Width;
- int Height;
- int MipLevels;
- int SampleCount; ///< Current only supported on depth textures
- ovrBool StaticImage; ///< Not buffered in a chain. For images that don't change
- unsigned int MiscFlags; ///< ovrTextureFlags
- unsigned int BindFlags; ///< ovrTextureBindFlags. Not used for GL.
-} ovrTextureSwapChainDesc;
-
-/// Description used to create a mirror texture.
-///
-/// \see ovr_CreateMirrorTextureDX
-/// \see ovr_CreateMirrorTextureGL
-///
-typedef struct ovrMirrorTextureDesc_
-{
- ovrTextureFormat Format;
- int Width;
- int Height;
- unsigned int MiscFlags; ///< ovrTextureFlags
-} ovrMirrorTextureDesc;
-
-typedef struct ovrTextureSwapChainData* ovrTextureSwapChain;
-typedef struct ovrMirrorTextureData* ovrMirrorTexture;
-
-//-----------------------------------------------------------------------------------
-
-/// Describes button input types.
-/// 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,
-
- ovrButton_X = 0x00000100,
- ovrButton_Y = 0x00000200,
- ovrButton_LThumb = 0x00000400,
- ovrButton_LShoulder = 0x00000800,
-
- // Navigation through DPad.
- ovrButton_Up = 0x00010000,
- ovrButton_Down = 0x00020000,
- ovrButton_Left = 0x00040000,
- ovrButton_Right = 0x00080000,
- ovrButton_Enter = 0x00100000, // Start on XBox controller.
- 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_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;
-
-/// Describes touch input types.
-/// These values map to capacitive touch values reported ovrInputState::Touch.
-/// Some of these values are mapped to button bits for consistency.
-typedef enum ovrTouch_
-{
- ovrTouch_A = ovrButton_A,
- ovrTouch_B = ovrButton_B,
- ovrTouch_RThumb = ovrButton_RThumb,
- ovrTouch_RThumbRest = 0x00000008,
- ovrTouch_RIndexTrigger = 0x00000010,
-
- // Bit mask of all the button touches on the right controller
- ovrTouch_RButtonMask = ovrTouch_A | ovrTouch_B | ovrTouch_RThumb | ovrTouch_RThumbRest | ovrTouch_RIndexTrigger,
-
- ovrTouch_X = ovrButton_X,
- ovrTouch_Y = ovrButton_Y,
- ovrTouch_LThumb = ovrButton_LThumb,
- ovrTouch_LThumbRest = 0x00000800,
- ovrTouch_LIndexTrigger = 0x00001000,
-
- // 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
- // Derived internally based on distance, proximity to sensors and filtering.
- ovrTouch_RIndexPointing = 0x00000020,
- ovrTouch_RThumbUp = 0x00000040,
-
- // Bit mask of all right controller poses
- ovrTouch_RPoseMask = ovrTouch_RIndexPointing | ovrTouch_RThumbUp,
-
- ovrTouch_LIndexPointing = 0x00002000,
- ovrTouch_LThumbUp = 0x00004000,
-
- // Bit mask of all left controller poses
- ovrTouch_LPoseMask = ovrTouch_LIndexPointing | ovrTouch_LThumbUp,
-
- 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_
-{
- ovrControllerType_None = 0x00,
- ovrControllerType_LTouch = 0x01,
- ovrControllerType_RTouch = 0x02,
- ovrControllerType_Touch = 0x03,
- ovrControllerType_Remote = 0x04,
- ovrControllerType_XBox = 0x10,
-
- ovrControllerType_Active = 0xff, ///< Operate on or query whichever controller is active.
-
- 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,
- ovrHand_Right = 1,
- ovrHand_Count = 2,
- ovrHand_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrHandType;
-
-
-
-/// ovrInputState describes the complete controller input state, including Oculus Touch,
-/// and XBox gamepad. If multiple inputs are connected and used at the same time,
-/// their inputs are combined.
-typedef struct ovrInputState_
-{
- /// System type when the controller state was last updated.
- double TimeInSeconds;
-
- /// Values for buttons described by ovrButton.
- unsigned int Buttons;
-
- /// 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.
- /// 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.
- float HandTrigger[ovrHand_Count];
-
- /// 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.
- 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;
-
-
-
-//-----------------------------------------------------------------------------------
-// ***** Initialize structures
-
-/// Initialization flags.
-///
-/// \see ovrInitParams, ovr_Initialize
-///
-typedef enum ovrInitFlags_
-{
- /// When a debug library is requested, a slower debugging version of the library will
- /// run which can be used to help solve problems in the library and debug application code.
- ovrInit_Debug = 0x00000001,
-
- /// When a version is requested, the LibOVR runtime respects the RequestedMinorVersion
- /// field and verifies that the RequestedMinorVersion is supported.
- ovrInit_RequestVersion = 0x00000004,
-
- // These bits are writable by user code.
- ovrinit_WritableBits = 0x00ffffff,
-
- ovrInit_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrInitFlags;
-
-
-/// Logging levels
-///
-/// \see ovrInitParams, ovrLogCallback
-///
-typedef enum ovrLogLevel_
-{
- ovrLogLevel_Debug = 0, ///< Debug-level log event.
- ovrLogLevel_Info = 1, ///< Info-level log event.
- ovrLogLevel_Error = 2, ///< Error-level log event.
-
- ovrLogLevel_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrLogLevel;
-
-
-/// Signature of the logging callback function pointer type.
-///
-/// \param[in] userData is an arbitrary value specified by the user of ovrInitParams.
-/// \param[in] level is one of the ovrLogLevel constants.
-/// \param[in] message is a UTF8-encoded null-terminated string.
-/// \see ovrInitParams, ovrLogLevel, ovr_Initialize
-///
-typedef void (OVR_CDECL* ovrLogCallback)(uintptr_t userData, int level, const char* message);
-
-
-/// Parameters for ovr_Initialize.
-///
-/// \see ovr_Initialize
-///
-typedef struct OVR_ALIGNAS(8) ovrInitParams_
-{
- /// Flags from ovrInitFlags to override default behavior.
- /// Use 0 for the defaults.
- uint32_t Flags;
-
- /// Requests a specific minimum minor version of the LibOVR runtime.
- /// Flags must include ovrInit_RequestVersion or this will be ignored
- /// and OVR_MINOR_VERSION will be used.
- uint32_t RequestedMinorVersion;
-
- /// User-supplied log callback function, which may be called at any time
- /// asynchronously from multiple threads until ovr_Shutdown completes.
- /// 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
- /// callback function.
- uintptr_t UserData;
-
- /// Relative number of milliseconds to wait for a connection to the server
- /// before failing. Use 0 for the default timeout.
- uint32_t ConnectionTimeoutMS;
-
- OVR_ON64(OVR_UNUSED_STRUCT_PAD(pad0, 4)) ///< \internal
-
-} ovrInitParams;
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined(OVR_EXPORTING_CAPI)
-
-// -----------------------------------------------------------------------------------
-// ***** API Interfaces
-
-/// Initializes LibOVR
-///
-/// Initialize LibOVR for application usage. This includes finding and loading the LibOVRRT
-/// shared library. No LibOVR API functions, other than ovr_GetLastErrorInfo and ovr_Detect, can
-/// be called unless ovr_Initialize succeeds. A successful call to ovr_Initialize must be eventually
-/// 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,
-/// but not if the module is a separate shared library).
-/// -# Application directory
-/// -# Development directory (only if OVR_ENABLE_DEVELOPER_SEARCH is enabled,
-/// which is off by default).
-/// -# Standard OS shared library search location(s) (OS-specific).
-///
-/// \param params Specifies custom initialization options. May be NULL to indicate default options.
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information. Example failed results include:
-/// - ovrError_Initialize: Generic initialization error.
-/// - ovrError_LibLoad: Couldn't load LibOVRRT.
-/// - ovrError_LibVersion: LibOVRRT version incompatibility.
-/// - ovrError_ServiceConnection: Couldn't connect to the OVR Service.
-/// - ovrError_ServiceVersion: OVR Service version incompatibility.
-/// - ovrError_IncompatibleOS: The operating system version is incompatible.
-/// - ovrError_DisplayInit: Unable to initialize the HMD display.
-/// - ovrError_ServerStart: Unable to start the server. Is it already running?
-/// - ovrError_Reinitialization: Attempted to re-initialize with a different version.
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ovrResult result = ovr_Initialize(NULL);
-/// if(OVR_FAILURE(result)) {
-/// ovrErrorInfo errorInfo;
-/// ovr_GetLastErrorInfo(&errorInfo);
-/// DebugLog("ovr_Initialize failed: %s", errorInfo.ErrorString);
-/// return false;
-/// }
-/// [...]
-/// \endcode
-///
-/// \see ovr_Shutdown
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_Initialize(const ovrInitParams* params);
-
-
-/// Shuts down LibOVR
-///
-/// A successful call to ovr_Initialize must be eventually matched by a call to ovr_Shutdown.
-/// After calling ovr_Shutdown, no LibOVR functions can be called except ovr_GetLastErrorInfo
-/// or another ovr_Initialize. ovr_Shutdown invalidates all pointers, references, and created objects
-/// previously returned by LibOVR functions. The LibOVRRT shared library can be unloaded by
-/// ovr_Shutdown.
-///
-/// \see ovr_Initialize
-///
-OVR_PUBLIC_FUNCTION(void) ovr_Shutdown();
-
-/// Returns information about the most recent failed return value by the
-/// current thread for this library.
-///
-/// This function itself can never generate an error.
-/// The last error is never cleared by LibOVR, but will be overwritten by new errors.
-/// Do not use this call to determine if there was an error in the last API
-/// call as successful API calls don't clear the last ovrErrorInfo.
-/// To avoid any inconsistency, ovr_GetLastErrorInfo should be called immediately
-/// after an API function that returned a failed ovrResult, with no other API
-/// functions called in the interim.
-///
-/// \param[out] errorInfo The last ovrErrorInfo for the current thread.
-///
-/// \see ovrErrorInfo
-///
-OVR_PUBLIC_FUNCTION(void) ovr_GetLastErrorInfo(ovrErrorInfo* errorInfo);
-
-
-/// Returns the version string representing the LibOVRRT version.
-///
-/// The returned string pointer is valid until the next call to ovr_Shutdown.
-///
-/// Note that the returned version string doesn't necessarily match the current
-/// OVR_MAJOR_VERSION, etc., as the returned string refers to the LibOVRRT shared
-/// library version and not the locally compiled interface version.
-///
-/// The format of this string is subject to change in future versions and its contents
-/// should not be interpreted.
-///
-/// \return Returns a UTF8-encoded null-terminated version string.
-///
-OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString();
-
-
-/// Writes a message string to the LibOVR tracing mechanism (if enabled).
-///
-/// This message will be passed back to the application via the ovrLogCallback if
-/// it was registered.
-///
-/// \param[in] level One of the ovrLogLevel constants.
-/// \param[in] message A UTF8-encoded null-terminated string.
-/// \return returns the strlen of the message or a negative value if the message is too large.
-///
-/// \see ovrLogLevel, ovrLogCallback
-///
-OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message);
-
-
-/// Identify client application info.
-///
-/// The string is one or more newline-delimited lines of optional info
-/// indicating engine name, engine version, engine plugin name, engine plugin
-/// version, engine editor. The order of the lines is not relevant. Individual
-/// lines are optional. A newline is not necessary at the end of the last line.
-/// Call after ovr_Initialize and before the first call to ovr_Create.
-/// Each value is limited to 20 characters. Key names such as 'EngineName:'
-/// 'EngineVersion:' do not count towards this limit.
-///
-/// \param[in] identity Specifies one or more newline-delimited lines of optional info:
-/// EngineName: %s\n
-/// EngineVersion: %s\n
-/// EnginePluginName: %s\n
-/// EnginePluginVersion: %s\n
-/// EngineEditor: <boolean> ('true' or 'false')\n
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ovr_IdentifyClient("EngineName: Unity\n"
-/// "EngineVersion: 5.3.3\n"
-/// "EnginePluginName: OVRPlugin\n"
-/// "EnginePluginVersion: 1.2.0\n"
-/// "EngineEditor: true");
-/// \endcode
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_IdentifyClient(const char* identity);
-
-
-//-------------------------------------------------------------------------------------
-/// @name HMD Management
-///
-/// Handles the enumeration, creation, destruction, and properties of an HMD (head-mounted display).
-///@{
-
-
-/// Returns information about the current HMD.
-///
-/// 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
-/// no HMD is present.
-///
-OVR_PUBLIC_FUNCTION(ovrHmdDesc) ovr_GetHmdDesc(ovrSession session);
-
-
-/// Returns the number of sensors.
-///
-/// 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.
-///
-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
-/// 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
-/// the sensor count returned by ovr_GetTrackerCount.
-///
-/// \return Returns ovrTrackerDesc. An empty ovrTrackerDesc will be returned if trackerDescIndex is out of range.
-///
-/// \see ovrTrackerDesc, ovr_GetTrackerCount
-///
-OVR_PUBLIC_FUNCTION(ovrTrackerDesc) ovr_GetTrackerDesc(ovrSession session, unsigned int trackerDescIndex);
-
-
-/// Creates a handle to a VR session.
-///
-/// Upon success the returned ovrSession must be eventually freed with ovr_Destroy when it is no longer needed.
-/// A second call to ovr_Create will result in an error return value if the previous session has not been destroyed.
-///
-/// \param[out] pSession Provides a pointer to an ovrSession which will be written to upon success.
-/// \param[out] luid Provides a system specific graphics adapter identifier that locates which
-/// graphics adapter has the HMD attached. This must match the adapter used by the application
-/// or no rendering output will be possible. This is important for stability on multi-adapter systems. An
-/// application that simply chooses the default adapter will not run reliably on multi-adapter systems.
-/// \return Returns an ovrResult indicating success or failure. Upon failure
-/// the returned ovrSession will be NULL.
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ovrSession session;
-/// ovrGraphicsLuid luid;
-/// ovrResult result = ovr_Create(&session, &luid);
-/// if(OVR_FAILURE(result))
-/// ...
-/// \endcode
-///
-/// \see ovr_Destroy
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_Create(ovrSession* pSession, ovrGraphicsLuid* pLuid);
-
-
-/// Destroys the session.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \see ovr_Create
-///
-OVR_PUBLIC_FUNCTION(void) ovr_Destroy(ovrSession session);
-
-#endif // !defined(OVR_EXPORTING_CAPI)
-
-/// Specifies status information for the current session.
-///
-/// \see ovr_GetSessionStatus
-///
-typedef struct ovrSessionStatus_
-{
- ovrBool IsVisible; ///< True if the process has VR focus and thus is visible in the HMD.
- 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 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.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[out] sessionStatus Provides an ovrSessionStatus that is filled in.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of
-/// failure, use ovr_GetLastErrorInfo to get more information.
-// Return values include but aren't limited to:
-/// - ovrSuccess: Completed successfully.
-/// - ovrError_ServiceConnection: The service connection was lost and the application
-// must destroy the session.
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetSessionStatus(ovrSession session, ovrSessionStatus* sessionStatus);
-
-
-//@}
-
-
-
-//-------------------------------------------------------------------------------------
-/// @name Tracking
-///
-/// Tracking functions handle the position, orientation, and movement of the HMD in space.
-///
-/// All tracking interface functions are thread-safe, allowing tracking state to be sampled
-/// from different threads.
-///
-///@{
-
-
-
-/// Sets the tracking origin type
-///
-/// 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
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-/// \see ovrTrackingOrigin, ovr_GetTrackingOriginType
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_SetTrackingOriginType(ovrSession session, ovrTrackingOrigin origin);
-
-
-/// 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.
-///
-/// \see ovrTrackingOrigin, ovr_SetTrackingOriginType
-OVR_PUBLIC_FUNCTION(ovrTrackingOrigin) ovr_GetTrackingOriginType(ovrSession session);
-
-
-/// Re-centers the sensor position and orientation.
-///
-/// 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
-/// 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.
-///
-/// For more info, see the notes on each ovrTrackingOrigin enumeration to understand how
-/// recenter will vary slightly in its behavior based on the current ovrTrackingOrigin setting.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information. Return values include but aren't limited to:
-/// - ovrSuccess: Completed successfully.
-/// - ovrError_InvalidHeadsetOrientation: The headset was facing an invalid direction when
-/// attempting recentering, such as facing vertically.
-///
-/// \see ovrTrackingOrigin, ovr_GetTrackerPose
-///
-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
-/// 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);
-
-
-/// Returns tracking state reading based on the specified absolute system time.
-///
-/// Pass an absTime value of 0.0 to request the most recent sensor reading. In this case
-/// both PredictedPose and SamplePose will have the same value.
-///
-/// This may also be used for more refined timing of front buffer rendering logic, and so on.
-/// This may be called by multiple threads.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] absTime Specifies the absolute future time to predict the return
-/// ovrTrackingState value. Use 0 to request the most recent tracking state.
-/// \param[in] latencyMarker Specifies that this call is the point in time where
-/// the "App-to-Mid-Photon" latency timer starts from. If a given ovrLayer
-/// provides "SensorSampleTime", that will override the value stored here.
-/// \return Returns the ovrTrackingState that is predicted for the given absTime.
-///
-/// \see ovrTrackingState, ovr_GetEyePoses, ovr_GetTimeInSeconds
-///
-OVR_PUBLIC_FUNCTION(ovrTrackingState) ovr_GetTrackingState(ovrSession session, double absTime, ovrBool latencyMarker);
-
-
-
-/// Returns the ovrTrackerPose for the given sensor.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] trackerPoseIndex Index of the sensor being requested.
-///
-/// \return Returns the requested ovrTrackerPose. An empty ovrTrackerPose will be returned if trackerPoseIndex is out of range.
-///
-/// \see ovr_GetTrackerCount
-///
-OVR_PUBLIC_FUNCTION(ovrTrackerPose) ovr_GetTrackerPose(ovrSession session, unsigned int trackerPoseIndex);
-
-
-
-/// Returns the most recent input state for controllers, without positional tracking info.
-///
-/// \param[out] inputState Input state that will be filled in.
-/// \param[in] ovrControllerType Specifies which controller the input will be returned for.
-/// \return Returns ovrSuccess if the new state was successfully obtained.
-///
-/// \see ovrControllerType
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetInputState(ovrSession session, ovrControllerType controllerType, ovrInputState* inputState);
-
-
-/// Returns controller types connected to the system OR'ed together.
-///
-/// \return A bitmask of ovrControllerTypes connected to the system.
-///
-/// \see ovrControllerType
-///
-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);
-
-/// Sets constant vibration (with specified frequency and amplitude) to a controller.
-/// Note: ovr_SetControllerVibration cannot be used interchangeably with ovr_SubmitControllerVibration.
-///
-/// 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 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.
-///
-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
-//
-///@{
-
-
-/// Specifies the maximum number of layers supported by ovr_SubmitFrame.
-///
-/// /see ovr_SubmitFrame
-///
-enum {
- ovrMaxLayerCount = 16
-};
-
-/// Describes layer types that can be passed to ovr_SubmitFrame.
-/// Each layer type has an associated struct, such as ovrLayerEyeFov.
-///
-/// \see ovrLayerHeader
-///
-typedef enum ovrLayerType_
-{
- ovrLayerType_Disabled = 0, ///< Layer is disabled.
- ovrLayerType_EyeFov = 1, ///< Described by ovrLayerEyeFov.
- ovrLayerType_Quad = 3, ///< Described by ovrLayerQuad. Previously called ovrLayerType_QuadInWorld.
- /// enum 4 used to be ovrLayerType_QuadHeadLocked. Instead, use ovrLayerType_Quad with ovrLayerFlag_HeadLocked.
- ovrLayerType_EyeMatrix = 5, ///< Described by ovrLayerEyeMatrix.
- ovrLayerType_EnumSize = 0x7fffffff ///< Force type int32_t.
-} ovrLayerType;
-
-
-/// Identifies flags used by ovrLayerHeader and which are passed to ovr_SubmitFrame.
-///
-/// \see ovrLayerHeader
-///
-typedef enum ovrLayerFlags_
-{
- /// ovrLayerFlag_HighQuality enables 4x anisotropic sampling during the composition of the layer.
- /// The benefits are mostly visible at the periphery for high-frequency & high-contrast visuals.
- /// For best results consider combining this flag with an ovrTextureSwapChain that has mipmaps and
- /// instead of using arbitrary sized textures, prefer texture sizes that are powers-of-two.
- /// Actual rendered viewport and doesn't necessarily have to fill the whole texture.
- ovrLayerFlag_HighQuality = 0x01,
-
- /// ovrLayerFlag_TextureOriginAtBottomLeft: the opposite is TopLeft.
- /// Generally this is false for D3D, true for OpenGL.
- ovrLayerFlag_TextureOriginAtBottomLeft = 0x02,
-
- /// Mark this surface as "headlocked", which means it is specified
- /// relative to the HMD and moves with it, rather than being specified
- /// relative to sensor/torso space and remaining still while the head moves.
- /// What used to be ovrLayerType_QuadHeadLocked is now ovrLayerType_Quad plus this flag.
- /// However the flag can be applied to any layer type to achieve a similar effect.
- ovrLayerFlag_HeadLocked = 0x04
-
-} ovrLayerFlags;
-
-
-/// Defines properties shared by all ovrLayer structs, such as ovrLayerEyeFov.
-///
-/// ovrLayerHeader is used as a base member in these larger structs.
-/// This struct cannot be used by itself except for the case that Type is ovrLayerType_Disabled.
-///
-/// \see ovrLayerType, ovrLayerFlags
-///
-typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerHeader_
-{
- ovrLayerType Type; ///< Described by ovrLayerType.
- unsigned Flags; ///< Described by ovrLayerFlags.
-} ovrLayerHeader;
-
-
-/// Describes a layer that specifies a monoscopic or stereoscopic view.
-/// This is the kind of layer that's typically used as layer 0 to ovr_SubmitFrame,
-/// as it is the kind of layer used to render a 3D stereoscopic view.
-///
-/// Three options exist with respect to mono/stereo texture usage:
-/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, respectively.
-/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively.
-/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL,
-/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0].
-/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and
-/// Viewport[1] both refer to that rendering.
-///
-/// \see ovrTextureSwapChain, ovr_SubmitFrame
-///
-typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeFov_
-{
- /// Header.Type must be ovrLayerType_EyeFov.
- ovrLayerHeader Header;
-
- /// ovrTextureSwapChains for the left and right eye respectively.
- /// The second one of which can be NULL for cases described above.
- ovrTextureSwapChain ColorTexture[ovrEye_Count];
-
- /// Specifies the ColorTexture sub-rect UV coordinates.
- /// Both Viewport[0] and Viewport[1] must be valid.
- ovrRecti Viewport[ovrEye_Count];
-
- /// The viewport field of view.
- ovrFovPort Fov[ovrEye_Count];
-
- /// Specifies the position and orientation of each eye view, with the position specified in meters.
- /// RenderPose will typically be the value returned from ovr_CalcEyePoses,
- /// but can be different in special cases if a different head pose is used for rendering.
- ovrPosef RenderPose[ovrEye_Count];
-
- /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose)
- /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds
- /// around the instant the application calls ovr_GetTrackingState
- /// The main purpose for this is to accurately track app tracking latency.
- double SensorSampleTime;
-
-} ovrLayerEyeFov;
-
-
-
-
-/// Describes a layer that specifies a monoscopic or stereoscopic view.
-/// This uses a direct 3x4 matrix to map from view space to the UV coordinates.
-/// It is essentially the same thing as ovrLayerEyeFov but using a much
-/// lower level. This is mainly to provide compatibility with specific apps.
-/// Unless the application really requires this flexibility, it is usually better
-/// to use ovrLayerEyeFov.
-///
-/// Three options exist with respect to mono/stereo texture usage:
-/// - ColorTexture[0] and ColorTexture[1] contain the left and right stereo renderings, respectively.
-/// Viewport[0] and Viewport[1] refer to ColorTexture[0] and ColorTexture[1], respectively.
-/// - ColorTexture[0] contains both the left and right renderings, ColorTexture[1] is NULL,
-/// and Viewport[0] and Viewport[1] refer to sub-rects with ColorTexture[0].
-/// - ColorTexture[0] contains a single monoscopic rendering, and Viewport[0] and
-/// Viewport[1] both refer to that rendering.
-///
-/// \see ovrTextureSwapChain, ovr_SubmitFrame
-///
-typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerEyeMatrix_
-{
- /// Header.Type must be ovrLayerType_EyeMatrix.
- ovrLayerHeader Header;
-
- /// ovrTextureSwapChains for the left and right eye respectively.
- /// The second one of which can be NULL for cases described above.
- ovrTextureSwapChain ColorTexture[ovrEye_Count];
-
- /// Specifies the ColorTexture sub-rect UV coordinates.
- /// Both Viewport[0] and Viewport[1] must be valid.
- ovrRecti Viewport[ovrEye_Count];
-
- /// Specifies the position and orientation of each eye view, with the position specified in meters.
- /// RenderPose will typically be the value returned from ovr_CalcEyePoses,
- /// but can be different in special cases if a different head pose is used for rendering.
- ovrPosef RenderPose[ovrEye_Count];
-
- /// Specifies the mapping from a view-space vector
- /// to a UV coordinate on the textures given above.
- /// P = (x,y,z,1)*Matrix
- /// TexU = P.x/P.z
- /// TexV = P.y/P.z
- ovrMatrix4f Matrix[ovrEye_Count];
-
- /// Specifies the timestamp when the source ovrPosef (used in calculating RenderPose)
- /// was sampled from the SDK. Typically retrieved by calling ovr_GetTimeInSeconds
- /// around the instant the application calls ovr_GetTrackingState
- /// The main purpose for this is to accurately track app tracking latency.
- double SensorSampleTime;
-
-} ovrLayerEyeMatrix;
-
-
-
-
-
-/// Describes a layer of Quad type, which is a single quad in world or viewer space.
-/// It is used for ovrLayerType_Quad. This type of layer represents a single
-/// object placed in the world and not a stereo view of the world itself.
-///
-/// A typical use of ovrLayerType_Quad is to draw a television screen in a room
-/// that for some reason is more convenient to draw as a layer than as part of the main
-/// view in layer 0. For example, it could implement a 3D popup GUI that is drawn at a
-/// higher resolution than layer 0 to improve fidelity of the GUI.
-///
-/// Quad layers are visible from both sides; they are not back-face culled.
-///
-/// \see ovrTextureSwapChain, ovr_SubmitFrame
-///
-typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) ovrLayerQuad_
-{
- /// Header.Type must be ovrLayerType_Quad.
- ovrLayerHeader Header;
-
- /// Contains a single image, never with any stereo view.
- ovrTextureSwapChain ColorTexture;
-
- /// Specifies the ColorTexture sub-rect UV coordinates.
- ovrRecti Viewport;
-
- /// Specifies the orientation and position of the center point of a Quad layer type.
- /// The supplied direction is the vector perpendicular to the quad.
- /// The position is in real-world meters (not the application's virtual world,
- /// the physical world the user is in) and is relative to the "zero" position
- /// set by ovr_RecenterTrackingOrigin unless the ovrLayerFlag_HeadLocked flag is used.
- ovrPosef QuadPoseCenter;
-
- /// Width and height (respectively) of the quad in meters.
- ovrVector2f QuadSize;
-
-} ovrLayerQuad;
-
-
-
-
-/// Union that combines ovrLayer types in a way that allows them
-/// to be used in a polymorphic way.
-typedef union ovrLayer_Union_
-{
- ovrLayerHeader Header;
- ovrLayerEyeFov EyeFov;
- ovrLayerQuad Quad;
-} ovrLayer_Union;
-
-
-//@}
-
-#if !defined(OVR_EXPORTING_CAPI)
-
-/// @name SDK Distortion Rendering
-///
-/// All of rendering functions including the configure and frame functions
-/// are not thread safe. It is OK to use ConfigureRendering on one thread and handle
-/// frames on another thread, but explicit synchronization must be done since
-/// functions that depend on configured state are not reentrant.
-///
-/// These functions support rendering of distortion by the SDK.
-///
-//@{
-
-/// TextureSwapChain creation is rendering API-specific.
-/// ovr_CreateTextureSwapChainDX and ovr_CreateTextureSwapChainGL can be found in the
-/// rendering API-specific headers, such as OVR_CAPI_D3D.h and OVR_CAPI_GL.h
-
-/// Gets the number of buffers in an ovrTextureSwapChain.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \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.
-///
-/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainLength(ovrSession session, ovrTextureSwapChain chain, int* out_Length);
-
-/// Gets the current index in an ovrTextureSwapChain.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \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.
-///
-/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainCurrentIndex(ovrSession session, ovrTextureSwapChain chain, int* out_Index);
-
-/// Gets the description of the buffers in an ovrTextureSwapChain
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \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.
-///
-/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainDesc(ovrSession session, ovrTextureSwapChain chain, ovrTextureSwapChainDesc* out_Desc);
-
-/// Commits any pending changes to an ovrTextureSwapChain, and advances its current index
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] chain Specifies the ovrTextureSwapChain to commit.
-///
-/// \note When Commit is called, the texture at the current index is considered ready for use by the
-/// runtime, and further writes to it should be avoided. The swap chain's current index is advanced,
-/// providing there's room in the chain. The next time the SDK dereferences this texture swap chain,
-/// 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.
-/// 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.
-///
-/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_CommitTextureSwapChain(ovrSession session, ovrTextureSwapChain chain);
-
-/// Destroys an ovrTextureSwapChain and frees all the resources associated with it.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] chain Specifies the ovrTextureSwapChain to destroy. If it is NULL then this function has no effect.
-///
-/// \see ovr_CreateTextureSwapChainDX, ovr_CreateTextureSwapChainGL
-///
-OVR_PUBLIC_FUNCTION(void) ovr_DestroyTextureSwapChain(ovrSession session, ovrTextureSwapChain chain);
-
-
-/// MirrorTexture creation is rendering API-specific.
-/// ovr_CreateMirrorTextureDX and ovr_CreateMirrorTextureGL can be found in the
-/// rendering API-specific headers, such as OVR_CAPI_D3D.h and OVR_CAPI_GL.h
-
-/// Destroys a mirror texture previously created by one of the mirror texture creation functions.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] mirrorTexture Specifies the ovrTexture to destroy. If it is NULL then this function has no effect.
-///
-/// \see ovr_CreateMirrorTextureDX, ovr_CreateMirrorTextureGL
-///
-OVR_PUBLIC_FUNCTION(void) ovr_DestroyMirrorTexture(ovrSession session, ovrMirrorTexture mirrorTexture);
-
-
-/// Calculates the recommended viewport size for rendering a given eye within the HMD
-/// with a given FOV cone.
-///
-/// Higher FOV will generally require larger textures to maintain quality.
-/// Apps packing multiple eye views together on the same texture should ensure there are
-/// at least 8 pixels of padding between them to prevent texture filtering and chromatic
-/// aberration causing images to leak between the two eye views.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] eye Specifies which eye (left or right) to calculate for.
-/// \param[in] fov Specifies the ovrFovPort to use.
-/// \param[in] pixelsPerDisplayPixel Specifies the ratio of the number of render target pixels
-/// to display pixels at the center of distortion. 1.0 is the default value. Lower
-/// values can improve performance, higher values give improved quality.
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
-/// ovrSizei eyeSizeLeft = ovr_GetFovTextureSize(session, ovrEye_Left, hmdDesc.DefaultEyeFov[ovrEye_Left], 1.0f);
-/// ovrSizei eyeSizeRight = ovr_GetFovTextureSize(session, ovrEye_Right, hmdDesc.DefaultEyeFov[ovrEye_Right], 1.0f);
-/// \endcode
-///
-/// \return Returns the texture width and height size.
-///
-OVR_PUBLIC_FUNCTION(ovrSizei) ovr_GetFovTextureSize(ovrSession session, ovrEyeType eye, ovrFovPort fov,
- float pixelsPerDisplayPixel);
-
-/// Computes the distortion viewport, view adjust, and other rendering parameters for
-/// the specified eye.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] eyeType Specifies which eye (left or right) for which to perform calculations.
-/// \param[in] fov Specifies the ovrFovPort to use.
-///
-/// \return Returns the computed ovrEyeRenderDesc for the given eyeType and field of view.
-///
-/// \see ovrEyeRenderDesc
-///
-OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovr_GetRenderDesc(ovrSession session,
- ovrEyeType eyeType, ovrFovPort fov);
-
-/// Submits layers for distortion and display.
-///
-/// ovr_SubmitFrame triggers distortion and processing which might happen asynchronously.
-/// The function will return when there is room in the submission queue and surfaces
-/// are available. Distortion might or might not have completed.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-///
-/// \param[in] frameIndex Specifies the targeted application frame index, or 0 to refer to one frame
-/// after the last time ovr_SubmitFrame was called.
-///
-/// \param[in] viewScaleDesc Provides additional information needed only if layerPtrList contains
-/// an ovrLayerType_Quad. If NULL, a default version is used based on the current configuration and a 1.0 world scale.
-///
-/// \param[in] layerPtrList Specifies a list of ovrLayer pointers, which can include NULL entries to
-/// indicate that any previously shown layer at that index is to not be displayed.
-/// Each layer header must be a part of a layer structure such as ovrLayerEyeFov or ovrLayerQuad,
-/// with Header.Type identifying its type. A NULL layerPtrList entry in the array indicates the
-// absence of the given layer.
-///
-/// \param[in] layerCount Indicates the number of valid elements in layerPtrList. The maximum
-/// supported layerCount is not currently specified, but may be specified in a future version.
-///
-/// - Layers are drawn in the order they are specified in the array, regardless of the layer type.
-///
-/// - Layers are not remembered between successive calls to ovr_SubmitFrame. A layer must be
-/// specified in every call to ovr_SubmitFrame or it won't be displayed.
-///
-/// - If a layerPtrList entry that was specified in a previous call to ovr_SubmitFrame is
-/// passed as NULL or is of type ovrLayerType_Disabled, that layer is no longer displayed.
-///
-/// - A layerPtrList entry can be of any layer type and multiple entries of the same layer type
-/// are allowed. No layerPtrList entry may be duplicated (i.e. the same pointer as an earlier entry).
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ovrLayerEyeFov layer0;
-/// ovrLayerQuad layer1;
-/// ...
-/// ovrLayerHeader* layers[2] = { &layer0.Header, &layer1.Header };
-/// ovrResult result = ovr_SubmitFrame(session, frameIndex, nullptr, layers, 2);
-/// \endcode
-///
-/// \return Returns an ovrResult for which OVR_SUCCESS(result) is false upon error and true
-/// upon success. Return values include but aren't limited to:
-/// - ovrSuccess: rendering completed successfully.
-/// - ovrSuccess_NotVisible: rendering completed successfully but was not displayed on the HMD,
-/// usually because another application currently has ownership of the HMD. Applications receiving
-/// this result should stop rendering new content, but continue to call ovr_SubmitFrame periodically
-/// until it returns a value other than ovrSuccess_NotVisible.
-/// - ovrError_DisplayLost: The session has become invalid (such as due to a device removal)
-/// and the shared resources need to be released (ovr_DestroyTextureSwapChain), the session needs to
-/// 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.
-/// Ensure ovr_CommitTextureSwapChain was called at least once first.
-///
-/// \see ovr_GetPredictedDisplayTime, ovrViewScaleDesc, ovrLayerHeader
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_SubmitFrame(ovrSession session, long long frameIndex,
- const ovrViewScaleDesc* viewScaleDesc,
- ovrLayerHeader const * const * layerPtrList, unsigned int layerCount);
-///@}
-
-#endif // !defined(OVR_EXPORTING_CAPI)
-
-//-------------------------------------------------------------------------------------
-/// @name Frame Timing
-///
-//@{
-
-
-#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.
-///
-/// The application should increment frameIndex for each successively targeted 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.
-/// \see ovr_GetTimeInSeconds
-///
-OVR_PUBLIC_FUNCTION(double) ovr_GetPredictedDisplayTime(ovrSession session, long long frameIndex);
-
-
-/// Returns global, absolute high-resolution time in seconds.
-///
-/// The time frame of reference for this function is not specified and should not be
-/// depended upon.
-///
-/// \return Returns seconds as a floating point value.
-/// \see ovrPoseStatef, ovrFrameTiming
-///
-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,
-/// and CPU & GPU performance metrics
-///
-/// App can toggle performance HUD modes as such:
-/// \code{.cpp}
-/// ovrPerfHudMode PerfHudMode = ovrPerfHud_LatencyTiming;
-/// ovr_SetInt(session, OVR_PERF_HUD_MODE, (int)PerfHudMode);
-/// \endcode
-///
-typedef enum ovrPerfHudMode_
-{
- ovrPerfHud_Off = 0, ///< Turns off the performance HUD
- ovrPerfHud_PerfSummary = 1, ///< Shows performance summary and headroom
- ovrPerfHud_LatencyTiming = 2, ///< Shows latency related timing info
- ovrPerfHud_AppRenderTiming = 3, ///< Shows render timing info for application
- ovrPerfHud_CompRenderTiming = 4, ///< Shows render timing info for OVR compositor
- ovrPerfHud_VersionInfo = 5, ///< Shows SDK & HMD version Info
- ovrPerfHud_Count = 6, ///< \internal Count of enumerated elements.
- ovrPerfHud_EnumSize = 0x7fffffff ///< \internal Force type int32_t.
-} ovrPerfHudMode;
-
-/// Layer HUD enables the HMD user to see information about a layer
-///
-/// App can toggle layer HUD modes as such:
-/// \code{.cpp}
-/// ovrLayerHudMode LayerHudMode = ovrLayerHud_Info;
-/// ovr_SetInt(session, OVR_LAYER_HUD_MODE, (int)LayerHudMode);
-/// \endcode
-///
-typedef enum ovrLayerHudMode_
-{
- ovrLayerHud_Off = 0, ///< Turns off the layer HUD
- ovrLayerHud_Info = 1, ///< Shows info about a specific layer
- ovrLayerHud_EnumSize = 0x7fffffff
-} 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,
-/// 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.
-///
-/// App can toggle the debug HUD modes as such:
-/// \code{.cpp}
-/// ovrDebugHudStereoMode DebugHudMode = ovrDebugHudStereo_QuadWithCrosshair;
-/// ovr_SetInt(session, OVR_DEBUG_HUD_STEREO_MODE, (int)DebugHudMode);
-/// \endcode
-///
-/// The app can modify the visual properties of the stereo guide (i.e. quad, crosshair)
-/// using the ovr_SetFloatArray function. For a list of tweakable properties,
-/// see the OVR_DEBUG_HUD_STEREO_GUIDE_* keys in the OVR_CAPI_Keys.h header file.
-typedef enum ovrDebugHudStereoMode_
-{
- ovrDebugHudStereo_Off = 0, ///< Turns off the Stereo Debug HUD
- ovrDebugHudStereo_Quad = 1, ///< Renders Quad in world for Stereo Debugging
- ovrDebugHudStereo_QuadWithCrosshair = 2, ///< Renders Quad+crosshair in world for Stereo Debugging
- ovrDebugHudStereo_CrosshairAtInfinity = 3, ///< Renders screen-space crosshair at infinity for Stereo Debugging
- ovrDebugHudStereo_Count, ///< \internal Count of enumerated elements
-
- ovrDebugHudStereo_EnumSize = 0x7fffffff ///< \internal Force type int32_t
-} ovrDebugHudStereoMode;
-
-
-#if !defined(OVR_EXPORTING_CAPI)
-
-// -----------------------------------------------------------------------------------
-/// @name Property Access
-///
-/// These functions read and write OVR properties. Supported properties
-/// are defined in OVR_CAPI_Keys.h
-///
-//@{
-
-/// Reads a boolean property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid for only the call.
-/// \param[in] defaultVal specifes the value to return if the property couldn't be read.
-/// \return Returns the property interpreted as a boolean value. Returns defaultVal if
-/// the property doesn't exist.
-OVR_PUBLIC_FUNCTION(ovrBool) ovr_GetBool(ovrSession session, const char* propertyName, ovrBool defaultVal);
-
-/// Writes or creates a boolean property.
-/// If the property wasn't previously a boolean property, it is changed to a boolean property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] value The value to write.
-/// \return Returns true if successful, otherwise false. A false result should only occur if the property
-/// name is empty or if the property is read-only.
-OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetBool(ovrSession session, const char* propertyName, ovrBool value);
-
-
-/// Reads an integer property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] defaultVal Specifes the value to return if the property couldn't be read.
-/// \return Returns the property interpreted as an integer value. Returns defaultVal if
-/// the property doesn't exist.
-OVR_PUBLIC_FUNCTION(int) ovr_GetInt(ovrSession session, const char* propertyName, int defaultVal);
-
-/// Writes or creates an integer property.
-///
-/// If the property wasn't previously a boolean property, it is changed to an integer property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] value The value to write.
-/// \return Returns true if successful, otherwise false. A false result should only occur if the property
-/// name is empty or if the property is read-only.
-OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetInt(ovrSession session, const char* propertyName, int value);
-
-
-/// Reads a float property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] defaultVal specifes the value to return if the property couldn't be read.
-/// \return Returns the property interpreted as an float value. Returns defaultVal if
-/// the property doesn't exist.
-OVR_PUBLIC_FUNCTION(float) ovr_GetFloat(ovrSession session, const char* propertyName, float defaultVal);
-
-/// Writes or creates a float property.
-/// If the property wasn't previously a float property, it's changed to a float property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] value The value to write.
-/// \return Returns true if successful, otherwise false. A false result should only occur if the property
-/// name is empty or if the property is read-only.
-OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetFloat(ovrSession session, const char* propertyName, float value);
-
-
-/// Reads a float array property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] values An array of float to write to.
-/// \param[in] valuesCapacity Specifies the maximum number of elements to write to the values array.
-/// \return Returns the number of elements read, or 0 if property doesn't exist or is empty.
-OVR_PUBLIC_FUNCTION(unsigned int) ovr_GetFloatArray(ovrSession session, const char* propertyName,
- float values[], unsigned int valuesCapacity);
-
-/// Writes or creates a float array property.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] values An array of float to write from.
-/// \param[in] valuesSize Specifies the number of elements to write.
-/// \return Returns true if successful, otherwise false. A false result should only occur if the property
-/// name is empty or if the property is read-only.
-OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetFloatArray(ovrSession session, const char* propertyName,
- const float values[], unsigned int valuesSize);
-
-
-/// Reads a string property.
-/// Strings are UTF8-encoded and null-terminated.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] defaultVal Specifes the value to return if the property couldn't be read.
-/// \return Returns the string property if it exists. Otherwise returns defaultVal, which can be specified as NULL.
-/// The return memory is guaranteed to be valid until next call to ovr_GetString or
-/// until the session is destroyed, whichever occurs first.
-OVR_PUBLIC_FUNCTION(const char*) ovr_GetString(ovrSession session, const char* propertyName,
- const char* defaultVal);
-
-/// Writes or creates a string property.
-/// Strings are UTF8-encoded and null-terminated.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] propertyName The name of the property, which needs to be valid only for the call.
-/// \param[in] value The string property, which only needs to be valid for the duration of the call.
-/// \return Returns true if successful, otherwise false. A false result should only occur if the property
-/// name is empty or if the property is read-only.
-OVR_PUBLIC_FUNCTION(ovrBool) ovr_SetString(ovrSession session, const char* propertyName,
- const char* value);
-
-///@}
-
-#endif // !defined(OVR_EXPORTING_CAPI)
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-
-#if defined(_MSC_VER)
- #pragma warning(pop)
-#endif
-
-/// @cond DoxygenIgnore
-//-----------------------------------------------------------------------------
-// ***** Compiler packing validation
-//
-// These checks ensure that the compiler settings being used will be compatible
-// with with pre-built dynamic library provided with the runtime.
-
-OVR_STATIC_ASSERT(sizeof(ovrBool) == 1, "ovrBool size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrVector2i) == 4 * 2, "ovrVector2i size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrSizei) == 4 * 2, "ovrSizei size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrRecti) == sizeof(ovrVector2i) + sizeof(ovrSizei), "ovrRecti size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrQuatf) == 4 * 4, "ovrQuatf size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrVector2f) == 4 * 2, "ovrVector2f size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrVector3f) == 4 * 3, "ovrVector3f size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrMatrix4f) == 4 * 16, "ovrMatrix4f size mismatch");
-
-OVR_STATIC_ASSERT(sizeof(ovrPosef) == (7 * 4), "ovrPosef size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrPoseStatef) == (22 * 4), "ovrPoseStatef size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrFovPort) == (4 * 4), "ovrFovPort size mismatch");
-
-OVR_STATIC_ASSERT(sizeof(ovrHmdCaps) == 4, "ovrHmdCaps size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrTrackingCaps) == 4, "ovrTrackingCaps size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrEyeType) == 4, "ovrEyeType size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrHmdType) == 4, "ovrHmdType size mismatch");
-
-OVR_STATIC_ASSERT(sizeof(ovrTrackerDesc) == 4 + 4 + 4 + 4, "ovrTrackerDesc size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrTrackerPose) == 4 + 4 + sizeof(ovrPosef) + sizeof(ovrPosef), "ovrTrackerPose size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrTrackingState) == sizeof(ovrPoseStatef) + 4 + 4 + (sizeof(ovrPoseStatef) * 2) + (sizeof(unsigned int) * 2) + sizeof(ovrPosef) + 4, "ovrTrackingState size mismatch");
-
-
-//OVR_STATIC_ASSERT(sizeof(ovrTextureHeader) == sizeof(ovrRenderAPIType) + sizeof(ovrSizei),
-// "ovrTextureHeader size mismatch");
-//OVR_STATIC_ASSERT(sizeof(ovrTexture) == sizeof(ovrTextureHeader) OVR_ON64(+4) + sizeof(uintptr_t) * 8,
-// "ovrTexture size mismatch");
-//
-OVR_STATIC_ASSERT(sizeof(ovrStatusBits) == 4, "ovrStatusBits size mismatch");
-
-OVR_STATIC_ASSERT(sizeof(ovrSessionStatus) == 6, "ovrSessionStatus size mismatch");
-
-OVR_STATIC_ASSERT(sizeof(ovrEyeRenderDesc) == sizeof(ovrEyeType) + sizeof(ovrFovPort) + sizeof(ovrRecti) +
- sizeof(ovrVector2f) + sizeof(ovrVector3f),
- "ovrEyeRenderDesc size mismatch");
-OVR_STATIC_ASSERT(sizeof(ovrTimewarpProjectionDesc) == 4 * 3, "ovrTimewarpProjectionDesc size mismatch");
-
-OVR_STATIC_ASSERT(sizeof(ovrInitFlags) == 4, "ovrInitFlags size mismatch");
-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) ==
- + sizeof(ovrHmdType) // Type
- OVR_ON64(+ 4) // pad0
- + 64 // ProductName
- + 64 // Manufacturer
- + 2 // VendorId
- + 2 // ProductId
- + 24 // SerialNumber
- + 2 // FirmwareMajor
- + 2 // FirmwareMinor
- + 4 * 4 // AvailableHmdCaps - DefaultTrackingCaps
- + sizeof(ovrFovPort) * 2 // DefaultEyeFov
- + sizeof(ovrFovPort) * 2 // MaxEyeFov
- + sizeof(ovrSizei) // Resolution
- + 4 // DisplayRefreshRate
- OVR_ON64(+ 4) // pad1
- , "ovrHmdDesc size mismatch");
-
-
-// -----------------------------------------------------------------------------------
-// ***** Backward compatibility #includes
-//
-// This is at the bottom of this file because the following is dependent on the
-// declarations above.
-
-#if !defined(OVR_CAPI_NO_UTILS)
- #include "Extras/OVR_CAPI_Util.h"
-#endif
-
-/// @endcond
-
-#endif // OVR_CAPI_h
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h
deleted file mode 100644
index dc61e19e..00000000
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Audio.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/********************************************************************************//**
-\file OVR_CAPI_Audio.h
-\brief CAPI audio functions.
-\copyright Copyright 2015 Oculus VR, LLC. All Rights reserved.
-************************************************************************************/
-
-
-#ifndef OVR_CAPI_Audio_h
-#define OVR_CAPI_Audio_h
-
-#ifdef _WIN32
-// Prevents <Windows.h> from defining min() and max() macro symbols.
-#ifndef NOMINMAX
-#define NOMINMAX
-#endif
-#include <windows.h>
-#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.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutWaveId(UINT* deviceOutId);
-
-/// Gets the ID of the preferred VR audio input device.
-///
-/// \param[out] deviceInId 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.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInWaveId(UINT* deviceInId);
-
-
-/// Gets the GUID of the preferred VR audio device as a string.
-///
-/// \param[out] deviceOutStrBuffer A buffer where the GUID string for the device will copied to.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuidStr(WCHAR deviceOutStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]);
-
-
-/// Gets the GUID of the preferred VR audio device.
-///
-/// \param[out] deviceOutGuid The GUID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be NULL.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceOutGuid(GUID* deviceOutGuid);
-
-
-/// Gets the GUID of the preferred VR microphone device as a string.
-///
-/// \param[out] deviceInStrBuffer A buffer where the GUID string for the device will copied to.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetAudioDeviceInGuidStr(WCHAR deviceInStrBuffer[OVR_AUDIO_MAX_DEVICE_STR_SIZE]);
-
-
-/// Gets the GUID of the preferred VR microphone device.
-///
-/// \param[out] deviceInGuid The GUID of the user's preferred VR audio device to use, which will be valid upon a successful return value, else it will be NULL.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-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
deleted file mode 100644
index 374dab84..00000000
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_D3D.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/********************************************************************************//**
-\file OVR_CAPI_D3D.h
-\brief D3D specific structures used by the CAPI interface.
-\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
-************************************************************************************/
-
-#ifndef OVR_CAPI_D3D_h
-#define OVR_CAPI_D3D_h
-
-#include "OVR_CAPI.h"
-#include "OVR_Version.h"
-
-
-#if defined (_WIN32)
-#include <Unknwn.h>
-
-#if !defined(OVR_EXPORTING_CAPI)
-
-//-----------------------------------------------------------------------------------
-// ***** Direct3D Specific
-
-/// Create Texture Swap Chain suitable for use with Direct3D 11 and 12.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with or the D3D12CommandQueue
-/// which must be the same one the application renders to the eye textures with.
-/// \param[in] desc Specifies requested texture properties. See notes for more info about texture format.
-/// \param[in] bindFlags Specifies what ovrTextureBindFlags the application requires for this texture chain.
-/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon a successful return value, else it will be NULL.
-/// This texture chain must be eventually destroyed via ovr_DestroyTextureSwapChain before destroying the session with ovr_Destroy.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-/// \note The texture format provided in \a desc should be thought of as the format the distortion-compositor will use for the
-/// ShaderResourceView when reading the contents of the texture. To that end, it is highly recommended that the application
-/// requests texture swapchain formats that are in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor
-/// does sRGB-correct rendering. As such, the compositor relies on the GPU's hardware sampler to do the sRGB-to-linear
-/// conversion. If the application still prefers to render to a linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) while handling the
-/// linear-to-gamma conversion via HLSL code, then the application must still request the corresponding sRGB format and also use
-/// the \a ovrTextureMisc_DX_Typeless flag in the ovrTextureSwapChainDesc's Flag field. This will allow the application to create
-/// a RenderTargetView that is the desired linear format while the compositor continues to treat it as sRGB. Failure to do so
-/// will cause the compositor to apply unexpected gamma conversions leading to gamma-curve artifacts. The \a ovrTextureMisc_DX_Typeless
-/// flag for depth buffer formats (e.g. OVR_FORMAT_D32_FLOAT) is ignored as they are always converted to be typeless.
-///
-/// \see ovr_GetTextureSwapChainLength
-/// \see ovr_GetTextureSwapChainCurrentIndex
-/// \see ovr_GetTextureSwapChainDesc
-/// \see ovr_GetTextureSwapChainBufferDX
-/// \see ovr_DestroyTextureSwapChain
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainDX(ovrSession session,
- IUnknown* d3dPtr,
- const ovrTextureSwapChainDesc* desc,
- ovrTextureSwapChain* out_TextureSwapChain);
-
-
-/// Get a specific buffer within the chain as any compatible COM interface (similar to QueryInterface)
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] chain Specifies an ovrTextureSwapChain previously returned by ovr_CreateTextureSwapChainDX
-/// \param[in] index Specifies the index within the chain to retrieve. Must be between 0 and length (see ovr_GetTextureSwapChainLength),
-/// or may pass -1 to get the buffer at the CurrentIndex location. (Saving a call to GetTextureSwapChainCurrentIndex)
-/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for.
-/// \param[out] out_Buffer Returns the COM interface pointer retrieved.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ovr_GetTextureSwapChainBufferDX(session, chain, 0, IID_ID3D11Texture2D, &d3d11Texture);
-/// ovr_GetTextureSwapChainBufferDX(session, chain, 1, IID_PPV_ARGS(&dxgiResource));
-/// \endcode
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferDX(ovrSession session,
- ovrTextureSwapChain chain,
- int index,
- IID iid,
- void** out_Buffer);
-
-
-/// Create Mirror Texture which is auto-refreshed to mirror Rift contents produced by this application.
-///
-/// A second call to ovr_CreateMirrorTextureDX for a given ovrSession before destroying the first one
-/// is not supported and will result in an error return.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] d3dPtr Specifies the application's D3D11Device to create resources with or the D3D12CommandQueue
-/// which must be the same one the application renders to the textures with.
-/// \param[in] desc Specifies requested texture properties. See notes for more info about texture format.
-/// \param[out] out_MirrorTexture Returns the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL.
-/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the session with ovr_Destroy.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-/// \note The texture format provided in \a desc should be thought of as the format the compositor will use for the RenderTargetView when
-/// writing into mirror texture. To that end, it is highly recommended that the application requests a mirror texture format that is
-/// in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the compositor does sRGB-correct rendering. If however the application wants
-/// to still read the mirror texture as a linear format (e.g. OVR_FORMAT_R8G8B8A8_UNORM) and handle the sRGB-to-linear conversion in
-/// HLSL code, then it is recommended the application still requests an sRGB format and also use the \a ovrTextureMisc_DX_Typeless flag in the
-/// ovrMirrorTextureDesc's Flags field. This will allow the application to bind a ShaderResourceView that is a linear format while the
-/// compositor continues to treat is as sRGB. Failure to do so will cause the compositor to apply unexpected gamma conversions leading to
-/// gamma-curve artifacts.
-///
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ovrMirrorTexture mirrorTexture = nullptr;
-/// ovrMirrorTextureDesc mirrorDesc = {};
-/// mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
-/// mirrorDesc.Width = mirrorWindowWidth;
-/// mirrorDesc.Height = mirrorWindowHeight;
-/// ovrResult result = ovr_CreateMirrorTextureDX(session, d3d11Device, &mirrorDesc, &mirrorTexture);
-/// [...]
-/// // Destroy the texture when done with it.
-/// ovr_DestroyMirrorTexture(session, mirrorTexture);
-/// mirrorTexture = nullptr;
-/// \endcode
-///
-/// \see ovr_GetMirrorTextureBufferDX
-/// \see ovr_DestroyMirrorTexture
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureDX(ovrSession session,
- IUnknown* d3dPtr,
- const ovrMirrorTextureDesc* desc,
- ovrMirrorTexture* out_MirrorTexture);
-
-/// Get a the underlying buffer as any compatible COM interface (similar to QueryInterface)
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned by ovr_CreateMirrorTextureDX
-/// \param[in] iid Specifies the interface ID of the interface pointer to query the buffer for.
-/// \param[out] out_Buffer Returns the COM interface pointer retrieved.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-/// <b>Example code</b>
-/// \code{.cpp}
-/// ID3D11Texture2D* d3d11Texture = nullptr;
-/// ovr_GetMirrorTextureBufferDX(session, mirrorTexture, IID_PPV_ARGS(&d3d11Texture));
-/// d3d11DeviceContext->CopyResource(d3d11TextureBackBuffer, d3d11Texture);
-/// d3d11Texture->Release();
-/// dxgiSwapChain->Present(0, 0);
-/// \endcode
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetMirrorTextureBufferDX(ovrSession session,
- ovrMirrorTexture mirrorTexture,
- IID iid,
- void** out_Buffer);
-
-#endif // !defined(OVR_EXPORTING_CAPI)
-
-#endif // _WIN32
-
-#endif // OVR_CAPI_D3D_h
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h
deleted file mode 100644
index 1c073f46..00000000
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/********************************************************************************//**
-\file OVR_CAPI_GL.h
-\brief OpenGL-specific structures used by the CAPI interface.
-\copyright Copyright 2015 Oculus VR, LLC. All Rights reserved.
-************************************************************************************/
-
-#ifndef OVR_CAPI_GL_h
-#define OVR_CAPI_GL_h
-
-#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.
-/// \param[in] desc Specifies the requested texture properties. See notes for more info about texture format.
-/// \param[out] out_TextureSwapChain Returns the created ovrTextureSwapChain, which will be valid upon
-/// a successful return value, else it will be NULL. This texture swap chain must be eventually
-/// destroyed via ovr_DestroyTextureSwapChain before destroying the session with ovr_Destroy.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-/// \note The \a format provided should be thought of as the format the distortion compositor will use when reading
-/// the contents of the texture. To that end, it is highly recommended that the application requests texture swap chain
-/// formats that are in sRGB-space (e.g. OVR_FORMAT_R8G8B8A8_UNORM_SRGB) as the distortion compositor does sRGB-correct
-/// rendering. Furthermore, the app should then make sure "glEnable(GL_FRAMEBUFFER_SRGB);" is called before rendering
-/// into these textures. Even though it is not recommended, if the application would like to treat the texture as a linear
-/// format and do linear-to-gamma conversion in GLSL, then the application can avoid calling "glEnable(GL_FRAMEBUFFER_SRGB);",
-/// but should still pass in an sRGB variant for the \a format. Failure to do so will cause the distortion compositor
-/// to apply incorrect gamma conversions leading to gamma-curve artifacts.
-///
-/// \see ovr_GetTextureSwapChainLength
-/// \see ovr_GetTextureSwapChainCurrentIndex
-/// \see ovr_GetTextureSwapChainDesc
-/// \see ovr_GetTextureSwapChainBufferGL
-/// \see ovr_DestroyTextureSwapChain
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateTextureSwapChainGL(ovrSession session,
- const ovrTextureSwapChainDesc* desc,
- ovrTextureSwapChain* out_TextureSwapChain);
-
-/// Get a specific buffer within the chain as a GL texture name
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] chain Specifies an ovrTextureSwapChain previously returned by ovr_CreateTextureSwapChainGL
-/// \param[in] index Specifies the index within the chain to retrieve. Must be between 0 and length (see ovr_GetTextureSwapChainLength)
-/// or may pass -1 to get the buffer at the CurrentIndex location. (Saving a call to GetTextureSwapChainCurrentIndex)
-/// \param[out] out_TexId Returns the GL texture object name associated with the specific index requested
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_GetTextureSwapChainBufferGL(ovrSession session,
- ovrTextureSwapChain chain,
- int index,
- unsigned int* out_TexId);
-
-
-/// Creates a Mirror Texture which is auto-refreshed to mirror Rift contents produced by this application.
-///
-/// A second call to ovr_CreateMirrorTextureGL for a given ovrSession before destroying the first one
-/// is not supported and will result in an error return.
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] desc Specifies the requested mirror texture description.
-/// \param[out] out_MirrorTexture Specifies the created ovrMirrorTexture, which will be valid upon a successful return value, else it will be NULL.
-/// This texture must be eventually destroyed via ovr_DestroyMirrorTexture before destroying the session with ovr_Destroy.
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-/// \note The \a format provided should be thought of as the format the distortion compositor will use when writing into the mirror
-/// texture. It is highly recommended that mirror textures are requested as sRGB formats because the distortion compositor
-/// does sRGB-correct rendering. If the application requests a non-sRGB format (e.g. R8G8B8A8_UNORM) as the mirror texture,
-/// then the application might have to apply a manual linear-to-gamma conversion when reading from the mirror texture.
-/// Failure to do so can result in incorrect gamma conversions leading to gamma-curve artifacts and color banding.
-///
-/// \see ovr_GetMirrorTextureBufferGL
-/// \see ovr_DestroyMirrorTexture
-///
-OVR_PUBLIC_FUNCTION(ovrResult) ovr_CreateMirrorTextureGL(ovrSession session,
- const ovrMirrorTextureDesc* desc,
- ovrMirrorTexture* out_MirrorTexture);
-
-/// Get a the underlying buffer as a GL texture name
-///
-/// \param[in] session Specifies an ovrSession previously returned by ovr_Create.
-/// \param[in] mirrorTexture Specifies an ovrMirrorTexture previously returned by ovr_CreateMirrorTextureGL
-/// \param[out] out_TexId Specifies the GL texture object name associated with the mirror texture
-///
-/// \return Returns an ovrResult indicating success or failure. In the case of failure, use
-/// ovr_GetLastErrorInfo to get more information.
-///
-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_CAPI_Keys.h b/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Keys.h
deleted file mode 100644
index e3e9d689..00000000
--- a/src/external/OculusSDK/LibOVR/Include/OVR_CAPI_Keys.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/********************************************************************************//**
-\file OVR_CAPI.h
-\brief Keys for CAPI proprty function calls
-\copyright Copyright 2015 Oculus VR, LLC All Rights reserved.
-************************************************************************************/
-
-#ifndef OVR_CAPI_Keys_h
-#define OVR_CAPI_Keys_h
-
-#include "OVR_Version.h"
-
-
-
-#define OVR_KEY_USER "User" // string
-
-#define OVR_KEY_NAME "Name" // string
-
-#define OVR_KEY_GENDER "Gender" // string "Male", "Female", or "Unknown"
-#define OVR_DEFAULT_GENDER "Unknown"
-
-#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" // float meters
-#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f
-
-#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float meters
-#define OVR_DEFAULT_EYE_HEIGHT 1.675f
-
-#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" // float[2] meters
-#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f
-#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f
-
-
-#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist" // float[2] meters
-
-
-
-
-
-#define OVR_PERF_HUD_MODE "PerfHudMode" // int, allowed values are defined in enum ovrPerfHudMode
-
-#define OVR_LAYER_HUD_MODE "LayerHudMode" // int, allowed values are defined in enum ovrLayerHudMode
-#define OVR_LAYER_HUD_CURRENT_LAYER "LayerHudCurrentLayer" // int, The layer to show
-#define OVR_LAYER_HUD_SHOW_ALL_LAYERS "LayerHudShowAll" // bool, Hide other layers when the hud is enabled
-
-#define OVR_DEBUG_HUD_STEREO_MODE "DebugHudStereoMode" // int, allowed values are defined in enum ovrDebugHudStereoMode
-#define OVR_DEBUG_HUD_STEREO_GUIDE_INFO_ENABLE "DebugHudStereoGuideInfoEnable" // bool
-#define OVR_DEBUG_HUD_STEREO_GUIDE_SIZE "DebugHudStereoGuideSize2f" // float[2]
-#define OVR_DEBUG_HUD_STEREO_GUIDE_POSITION "DebugHudStereoGuidePosition3f" // float[3]
-#define OVR_DEBUG_HUD_STEREO_GUIDE_YAWPITCHROLL "DebugHudStereoGuideYawPitchRoll3f" // float[3]
-#define OVR_DEBUG_HUD_STEREO_GUIDE_COLOR "DebugHudStereoGuideColor4f" // float[4]
-
-
-
-#endif // OVR_CAPI_Keys_h
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h b/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h
deleted file mode 100644
index a8b810ea..00000000
--- a/src/external/OculusSDK/LibOVR/Include/OVR_ErrorCode.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/********************************************************************************//**
-\file OVR_ErrorCode.h
-\brief This header provides LibOVR error code declarations.
-\copyright Copyright 2015-2016 Oculus VR, LLC All Rights reserved.
-*************************************************************************************/
-
-#ifndef OVR_ErrorCode_h
-#define OVR_ErrorCode_h
-
-
-#include "OVR_Version.h"
-#include <stdint.h>
-
-
-
-
-#ifndef OVR_RESULT_DEFINED
-#define OVR_RESULT_DEFINED ///< Allows ovrResult to be independently defined.
-/// API call results are represented at the highest level by a single ovrResult.
-typedef int32_t ovrResult;
-#endif
-
-
-/// \brief Indicates if an ovrResult indicates success.
-///
-/// Some functions return additional successful values other than ovrSucces and
-/// require usage of this macro to indicate successs.
-///
-#if !defined(OVR_SUCCESS)
- #define OVR_SUCCESS(result) (result >= 0)
-#endif
-
-
-/// \brief Indicates if an ovrResult indicates an unqualified success.
-///
-/// This is useful for indicating that the code intentionally wants to
-/// check for result == ovrSuccess as opposed to OVR_SUCCESS(), which
-/// checks for result >= ovrSuccess.
-///
-#if !defined(OVR_UNQUALIFIED_SUCCESS)
- #define OVR_UNQUALIFIED_SUCCESS(result) (result == ovrSuccess)
-#endif
-
-
-/// \brief Indicates if an ovrResult indicates failure.
-///
-#if !defined(OVR_FAILURE)
- #define OVR_FAILURE(result) (!OVR_SUCCESS(result))
-#endif
-
-
-// Success is a value greater or equal to 0, while all error types are negative values.
-#ifndef OVR_SUCCESS_DEFINED
-#define OVR_SUCCESS_DEFINED ///< Allows ovrResult to be independently defined.
-typedef enum ovrSuccessType_
-{
- /// This is a general success result. Use OVR_SUCCESS to test for success.
- ovrSuccess = 0,
-} ovrSuccessType;
-#endif
-
-// Public success types
-// Success is a value greater or equal to 0, while all error types are negative values.
-typedef enum ovrSuccessTypes_
-{
- /// Returned from a call to SubmitFrame. The call succeeded, but what the app
- /// rendered will not be visible on the HMD. Ideally the app should continue
- /// calling SubmitFrame, but not do any rendering. When the result becomes
- /// ovrSuccess, rendering should continue as usual.
- ovrSuccess_NotVisible = 1000,
-
-} ovrSuccessTypes;
-
-// Public error types
-typedef enum ovrErrorType_
-{
- /* General errors */
- ovrError_MemoryAllocationFailure = -1000, ///< Failure to allocate memory.
- ovrError_InvalidSession = -1002, ///< Invalid ovrSession parameter provided.
- ovrError_Timeout = -1003, ///< The operation timed out.
- ovrError_NotInitialized = -1004, ///< The system or component has not been initialized.
- ovrError_InvalidParameter = -1005, ///< Invalid parameter provided. See error info or log for details.
- ovrError_ServiceError = -1006, ///< Generic service error. See error info or log for details.
- ovrError_NoHmd = -1007, ///< The given HMD doesn't exist.
- ovrError_Unsupported = -1009, ///< Function call is not supported on this hardware/software
- ovrError_DeviceUnavailable = -1010, ///< Specified device type isn't available.
- ovrError_InvalidHeadsetOrientation = -1011, ///< The headset was in an invalid orientation for the requested operation (e.g. vertically oriented during ovr_RecenterPose).
- 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.
- ovrError_AudioComError = -2002, ///< Generic COM error.
-
- /* Initialization errors. */
- ovrError_Initialize = -3000, ///< Generic initialization error.
- ovrError_LibLoad = -3001, ///< Couldn't load LibOVRRT.
- ovrError_LibVersion = -3002, ///< LibOVRRT version incompatibility.
- ovrError_ServiceConnection = -3003, ///< Couldn't connect to the OVR Service.
- ovrError_ServiceVersion = -3004, ///< OVR Service version incompatibility.
- ovrError_IncompatibleOS = -3005, ///< The operating system version is incompatible.
- ovrError_DisplayInit = -3006, ///< Unable to initialize the HMD display.
- ovrError_ServerStart = -3007, ///< Unable to start the server. Is it already running?
- ovrError_Reinitialization = -3008, ///< Attempting to re-initialize with a different version.
- ovrError_MismatchedAdapters = -3009, ///< Chosen rendering adapters between client and service do not match
- ovrError_LeakingResources = -3010, ///< Calling application has leaked resources
- ovrError_ClientVersion = -3011, ///< Client version too old to connect to service
- ovrError_OutOfDateOS = -3012, ///< The operating system is out of date.
- ovrError_OutOfDateGfxDriver = -3013, ///< The graphics driver is out of date.
- ovrError_IncompatibleGPU = -3014, ///< The graphics hardware is not supported
- ovrError_NoValidVRDisplaySystem = -3015, ///< No valid VR display system found.
- ovrError_Obsolete = -3016, ///< Feature or API is obsolete and no longer supported.
- ovrError_DisabledOrDefaultAdapter = -3017, ///< No supported VR display system found, but disabled or driverless adapter found.
- 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.
- ovrError_TextureSwapChainFull = -6001, ///< ovr_CommitTextureSwapChain was called too many times on a texture swapchain without calling submit to use the chain.
- ovrError_TextureSwapChainInvalid = -6002, ///< The ovrTextureSwapChain is in an incomplete or inconsistent state. Ensure ovr_CommitTextureSwapChain was called at least once first.
- ovrError_GraphicsDeviceReset = -6003, ///< Graphics device has been reset (TDR, etc...)
- ovrError_DisplayRemoved = -6004, ///< HMD removed from the display adapter
- ovrError_ContentProtectionNotAvailable = -6005,///<Content protection is not available for the display
- ovrError_ApplicationInvisible = -6006, ///< Application declared itself as an invisible type and is not allowed to submit frames.
- ovrError_Disallowed = -6007, ///< The given request is disallowed under the current conditions.
- ovrError_DisplayPluggedIncorrectly = -6008, ///< Display portion of HMD is plugged into an incompatible port (ex: IGP)
-
- /* 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;
-
-
-
-/// Provides information about the last error.
-/// \see ovr_GetLastErrorInfo
-typedef struct ovrErrorInfo_
-{
- ovrResult Result; ///< The result from the last API call that generated an error ovrResult.
- char ErrorString[512]; ///< A UTF8-encoded null-terminated English string describing the problem. The format of this string is subject to change in future versions.
-} ovrErrorInfo;
-
-
-#endif /* OVR_ErrorCode_h */
diff --git a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h b/src/external/OculusSDK/LibOVR/Include/OVR_Version.h
deleted file mode 100644
index 8d213df5..00000000
--- a/src/external/OculusSDK/LibOVR/Include/OVR_Version.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/********************************************************************************//**
-\file OVR_Version.h
-\brief This header provides LibOVR version identification.
-\copyright Copyright 2014-2016 Oculus VR, LLC All Rights reserved.
-*************************************************************************************/
-
-#ifndef OVR_Version_h
-#define OVR_Version_h
-
-
-
-/// Conventional string-ification macro.
-#if !defined(OVR_STRINGIZE)
- #define OVR_STRINGIZEIMPL(x) #x
- #define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x)
-#endif
-
-
-// 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 7 //
-#define OVR_PATCH_VERSION 0
-#define OVR_BUILD_NUMBER 0
-
-// This is the ((product * 100) + major) version of the service that the DLL is compatible with.
-// When we backport changes to old versions of the DLL we update the old DLLs
-// to move this version number up to the latest version.
-// The DLL is responsible for checking that the service is the version it supports
-// and returning an appropriate error message if it has not been made compatible.
-#define OVR_DLL_COMPATIBLE_VERSION 101
-
-#define OVR_FEATURE_VERSION 0
-
-
-/// "Major.Minor.Patch"
-#if !defined(OVR_VERSION_STRING)
- #define OVR_VERSION_STRING OVR_STRINGIZE(OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION)
-#endif
-
-
-/// "Major.Minor.Patch.Build"
-#if !defined(OVR_DETAILED_VERSION_STRING)
- #define OVR_DETAILED_VERSION_STRING OVR_STRINGIZE(OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION.OVR_BUILD_NUMBER)
-#endif
-
-
-/// \brief file description for version info
-/// This appears in the user-visible file properties. It is intended to convey publicly
-/// available additional information such as feature builds.
-#if !defined(OVR_FILE_DESCRIPTION_STRING)
- #if defined(_DEBUG)
- #define OVR_FILE_DESCRIPTION_STRING "dev build debug"
- #else
- #define OVR_FILE_DESCRIPTION_STRING "dev build"
- #endif
-#endif
-
-
-#endif // OVR_Version_h
diff --git a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll b/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll
deleted file mode 100644
index 7a42d443..00000000
--- a/src/external/OculusSDK/LibOVR/LibOVRRT32_1.dll
+++ /dev/null
Binary files differ
diff --git a/src/external/android/native_app_glue/Android.mk b/src/external/android/native_app_glue/Android.mk
new file mode 100644
index 00000000..00252fcb
--- /dev/null
+++ b/src/external/android/native_app_glue/Android.mk
@@ -0,0 +1,10 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= android_native_app_glue
+LOCAL_SRC_FILES:= android_native_app_glue.c
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_EXPORT_LDLIBS := -llog
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/src/external/android/native_app_glue/NOTICE b/src/external/android/native_app_glue/NOTICE
new file mode 100644
index 00000000..d6c09229
--- /dev/null
+++ b/src/external/android/native_app_glue/NOTICE
@@ -0,0 +1,13 @@
+Copyright (C) 2016 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/src/external/android/native_app_glue/android_native_app_glue.c b/src/external/android/native_app_glue/android_native_app_glue.c
new file mode 100644
index 00000000..d503d8da
--- /dev/null
+++ b/src/external/android/native_app_glue/android_native_app_glue.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <jni.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/resource.h>
+
+#include "android_native_app_glue.h"
+#include <android/log.h>
+
+#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
+#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
+
+/* For debug builds, always enable the debug traces in this library */
+#ifndef NDEBUG
+# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__))
+#else
+# define LOGV(...) ((void)0)
+#endif
+
+static void free_saved_state(struct android_app* android_app) {
+ pthread_mutex_lock(&android_app->mutex);
+ if (android_app->savedState != NULL) {
+ free(android_app->savedState);
+ android_app->savedState = NULL;
+ android_app->savedStateSize = 0;
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
+int8_t android_app_read_cmd(struct android_app* android_app) {
+ int8_t cmd;
+ if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
+ switch (cmd) {
+ case APP_CMD_SAVE_STATE:
+ free_saved_state(android_app);
+ break;
+ }
+ return cmd;
+ } else {
+ LOGE("No data on command pipe!");
+ }
+ return -1;
+}
+
+static void print_cur_config(struct android_app* android_app) {
+ char lang[2], country[2];
+ AConfiguration_getLanguage(android_app->config, lang);
+ AConfiguration_getCountry(android_app->config, country);
+
+ LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
+ "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
+ "modetype=%d modenight=%d",
+ AConfiguration_getMcc(android_app->config),
+ AConfiguration_getMnc(android_app->config),
+ lang[0], lang[1], country[0], country[1],
+ AConfiguration_getOrientation(android_app->config),
+ AConfiguration_getTouchscreen(android_app->config),
+ AConfiguration_getDensity(android_app->config),
+ AConfiguration_getKeyboard(android_app->config),
+ AConfiguration_getNavigation(android_app->config),
+ AConfiguration_getKeysHidden(android_app->config),
+ AConfiguration_getNavHidden(android_app->config),
+ AConfiguration_getSdkVersion(android_app->config),
+ AConfiguration_getScreenSize(android_app->config),
+ AConfiguration_getScreenLong(android_app->config),
+ AConfiguration_getUiModeType(android_app->config),
+ AConfiguration_getUiModeNight(android_app->config));
+}
+
+void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
+ switch (cmd) {
+ case APP_CMD_INPUT_CHANGED:
+ LOGV("APP_CMD_INPUT_CHANGED\n");
+ pthread_mutex_lock(&android_app->mutex);
+ if (android_app->inputQueue != NULL) {
+ AInputQueue_detachLooper(android_app->inputQueue);
+ }
+ android_app->inputQueue = android_app->pendingInputQueue;
+ if (android_app->inputQueue != NULL) {
+ LOGV("Attaching input queue to looper");
+ AInputQueue_attachLooper(android_app->inputQueue,
+ android_app->looper, LOOPER_ID_INPUT, NULL,
+ &android_app->inputPollSource);
+ }
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ break;
+
+ case APP_CMD_INIT_WINDOW:
+ LOGV("APP_CMD_INIT_WINDOW\n");
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->window = android_app->pendingWindow;
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ break;
+
+ case APP_CMD_TERM_WINDOW:
+ LOGV("APP_CMD_TERM_WINDOW\n");
+ pthread_cond_broadcast(&android_app->cond);
+ break;
+
+ case APP_CMD_RESUME:
+ case APP_CMD_START:
+ case APP_CMD_PAUSE:
+ case APP_CMD_STOP:
+ LOGV("activityState=%d\n", cmd);
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->activityState = cmd;
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ break;
+
+ case APP_CMD_CONFIG_CHANGED:
+ LOGV("APP_CMD_CONFIG_CHANGED\n");
+ AConfiguration_fromAssetManager(android_app->config,
+ android_app->activity->assetManager);
+ print_cur_config(android_app);
+ break;
+
+ case APP_CMD_DESTROY:
+ LOGV("APP_CMD_DESTROY\n");
+ android_app->destroyRequested = 1;
+ break;
+ }
+}
+
+void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
+ switch (cmd) {
+ case APP_CMD_TERM_WINDOW:
+ LOGV("APP_CMD_TERM_WINDOW\n");
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->window = NULL;
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ break;
+
+ case APP_CMD_SAVE_STATE:
+ LOGV("APP_CMD_SAVE_STATE\n");
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->stateSaved = 1;
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ break;
+
+ case APP_CMD_RESUME:
+ free_saved_state(android_app);
+ break;
+ }
+}
+
+void app_dummy() {
+
+}
+
+static void android_app_destroy(struct android_app* android_app) {
+ LOGV("android_app_destroy!");
+ free_saved_state(android_app);
+ pthread_mutex_lock(&android_app->mutex);
+ if (android_app->inputQueue != NULL) {
+ AInputQueue_detachLooper(android_app->inputQueue);
+ }
+ AConfiguration_delete(android_app->config);
+ android_app->destroyed = 1;
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ // Can't touch android_app object after this.
+}
+
+static void process_input(struct android_app* app, struct android_poll_source* source) {
+ AInputEvent* event = NULL;
+ while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
+ LOGV("New input event: type=%d\n", AInputEvent_getType(event));
+ if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
+ continue;
+ }
+ int32_t handled = 0;
+ if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
+ AInputQueue_finishEvent(app->inputQueue, event, handled);
+ }
+}
+
+static void process_cmd(struct android_app* app, struct android_poll_source* source) {
+ int8_t cmd = android_app_read_cmd(app);
+ android_app_pre_exec_cmd(app, cmd);
+ if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
+ android_app_post_exec_cmd(app, cmd);
+}
+
+static void* android_app_entry(void* param) {
+ struct android_app* android_app = (struct android_app*)param;
+
+ android_app->config = AConfiguration_new();
+ AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
+
+ print_cur_config(android_app);
+
+ android_app->cmdPollSource.id = LOOPER_ID_MAIN;
+ android_app->cmdPollSource.app = android_app;
+ android_app->cmdPollSource.process = process_cmd;
+ android_app->inputPollSource.id = LOOPER_ID_INPUT;
+ android_app->inputPollSource.app = android_app;
+ android_app->inputPollSource.process = process_input;
+
+ ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
+ ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
+ &android_app->cmdPollSource);
+ android_app->looper = looper;
+
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->running = 1;
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+
+ android_main(android_app);
+
+ android_app_destroy(android_app);
+ return NULL;
+}
+
+// --------------------------------------------------------------------
+// Native activity interaction (called from main thread)
+// --------------------------------------------------------------------
+
+static struct android_app* android_app_create(ANativeActivity* activity,
+ void* savedState, size_t savedStateSize) {
+ struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app));
+ memset(android_app, 0, sizeof(struct android_app));
+ android_app->activity = activity;
+
+ pthread_mutex_init(&android_app->mutex, NULL);
+ pthread_cond_init(&android_app->cond, NULL);
+
+ if (savedState != NULL) {
+ android_app->savedState = malloc(savedStateSize);
+ android_app->savedStateSize = savedStateSize;
+ memcpy(android_app->savedState, savedState, savedStateSize);
+ }
+
+ int msgpipe[2];
+ if (pipe(msgpipe)) {
+ LOGE("could not create pipe: %s", strerror(errno));
+ return NULL;
+ }
+ android_app->msgread = msgpipe[0];
+ android_app->msgwrite = msgpipe[1];
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
+
+ // Wait for thread to start.
+ pthread_mutex_lock(&android_app->mutex);
+ while (!android_app->running) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+
+ return android_app;
+}
+
+static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
+ if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
+ LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
+ }
+}
+
+static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->pendingInputQueue = inputQueue;
+ android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
+ while (android_app->inputQueue != android_app->pendingInputQueue) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
+static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
+ pthread_mutex_lock(&android_app->mutex);
+ if (android_app->pendingWindow != NULL) {
+ android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
+ }
+ android_app->pendingWindow = window;
+ if (window != NULL) {
+ android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
+ }
+ while (android_app->window != android_app->pendingWindow) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
+static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
+ pthread_mutex_lock(&android_app->mutex);
+ android_app_write_cmd(android_app, cmd);
+ while (android_app->activityState != cmd) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
+static void android_app_free(struct android_app* android_app) {
+ pthread_mutex_lock(&android_app->mutex);
+ android_app_write_cmd(android_app, APP_CMD_DESTROY);
+ while (!android_app->destroyed) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+
+ close(android_app->msgread);
+ close(android_app->msgwrite);
+ pthread_cond_destroy(&android_app->cond);
+ pthread_mutex_destroy(&android_app->mutex);
+ free(android_app);
+}
+
+static void onDestroy(ANativeActivity* activity) {
+ LOGV("Destroy: %p\n", activity);
+ android_app_free((struct android_app*)activity->instance);
+}
+
+static void onStart(ANativeActivity* activity) {
+ LOGV("Start: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START);
+}
+
+static void onResume(ANativeActivity* activity) {
+ LOGV("Resume: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME);
+}
+
+static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
+ struct android_app* android_app = (struct android_app*)activity->instance;
+ void* savedState = NULL;
+
+ LOGV("SaveInstanceState: %p\n", activity);
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->stateSaved = 0;
+ android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
+ while (!android_app->stateSaved) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+
+ if (android_app->savedState != NULL) {
+ savedState = android_app->savedState;
+ *outLen = android_app->savedStateSize;
+ android_app->savedState = NULL;
+ android_app->savedStateSize = 0;
+ }
+
+ pthread_mutex_unlock(&android_app->mutex);
+
+ return savedState;
+}
+
+static void onPause(ANativeActivity* activity) {
+ LOGV("Pause: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE);
+}
+
+static void onStop(ANativeActivity* activity) {
+ LOGV("Stop: %p\n", activity);
+ android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP);
+}
+
+static void onConfigurationChanged(ANativeActivity* activity) {
+ struct android_app* android_app = (struct android_app*)activity->instance;
+ LOGV("ConfigurationChanged: %p\n", activity);
+ android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
+}
+
+static void onLowMemory(ANativeActivity* activity) {
+ struct android_app* android_app = (struct android_app*)activity->instance;
+ LOGV("LowMemory: %p\n", activity);
+ android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
+}
+
+static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
+ LOGV("WindowFocusChanged: %p -- %d\n", activity, focused);
+ android_app_write_cmd((struct android_app*)activity->instance,
+ focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
+}
+
+static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
+ LOGV("NativeWindowCreated: %p -- %p\n", activity, window);
+ android_app_set_window((struct android_app*)activity->instance, window);
+}
+
+static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
+ LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window);
+ android_app_set_window((struct android_app*)activity->instance, NULL);
+}
+
+static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
+ LOGV("InputQueueCreated: %p -- %p\n", activity, queue);
+ android_app_set_input((struct android_app*)activity->instance, queue);
+}
+
+static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
+ LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue);
+ android_app_set_input((struct android_app*)activity->instance, NULL);
+}
+
+void ANativeActivity_onCreate(ANativeActivity* activity,
+ void* savedState, size_t savedStateSize) {
+ LOGV("Creating: %p\n", activity);
+ activity->callbacks->onDestroy = onDestroy;
+ activity->callbacks->onStart = onStart;
+ activity->callbacks->onResume = onResume;
+ activity->callbacks->onSaveInstanceState = onSaveInstanceState;
+ activity->callbacks->onPause = onPause;
+ activity->callbacks->onStop = onStop;
+ activity->callbacks->onConfigurationChanged = onConfigurationChanged;
+ activity->callbacks->onLowMemory = onLowMemory;
+ activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
+ activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
+ activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
+ activity->callbacks->onInputQueueCreated = onInputQueueCreated;
+ activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
+
+ activity->instance = android_app_create(activity, savedState, savedStateSize);
+}
diff --git a/src/android/jni/include/android_native_app_glue.h b/src/external/android/native_app_glue/android_native_app_glue.h
index 1b8c1f10..97202e09 100644
--- a/src/android/jni/include/android_native_app_glue.h
+++ b/src/external/android/native_app_glue/android_native_app_glue.h
@@ -39,7 +39,7 @@ extern "C" {
* risk having the system force-close the application. This programming
* model is direct, lightweight, but constraining.
*
- * The 'threaded_native_app' static library is used to provide a different
+ * The 'android_native_app_glue' static library is used to provide a different
* execution model where the application can implement its own main event
* loop in a different thread instead. Here's how it works:
*
diff --git a/src/external/gif.h b/src/external/gif.h
new file mode 100644
index 00000000..1c0aeb18
--- /dev/null
+++ b/src/external/gif.h
@@ -0,0 +1,931 @@
+/**********************************************************************************************
+*
+* gif.h by Charlie Tangora [ctangora -at- gmail -dot- com]
+* adapted to C99 and reformatted by Ramon Santamaria (@raysan5)
+*
+* This file offers a simple, very limited way to create animated GIFs directly in code.
+*
+* Those looking for particular cleverness are likely to be disappointed; it's pretty
+* much a straight-ahead implementation of the GIF format with optional Floyd-Steinberg
+* dithering. (It does at least use delta encoding - only the changed portions of each
+* frame are saved.)
+*
+* So resulting files are often quite large. The hope is that it will be handy nonetheless
+* as a quick and easily-integrated way for programs to spit out animations.
+*
+* Only RGBA8 is currently supported as an input format. (The alpha is ignored.)
+*
+* CONFIGURATION:
+*
+* #define GIF_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.
+*
+* USAGE:
+* 1) Create a GifWriter struct. Pass it to GifBegin() to initialize and write the header.
+* 2) Pass subsequent frames to GifWriteFrame().
+* 3) Finally, call GifEnd() to close the file handle and free memory.
+*
+*
+* LICENSE: public domain (www.unlicense.org)
+*
+* This is free and unencumbered software released into the public domain.
+* Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+* software, either in source code form or as a compiled binary, for any purpose,
+* commercial or non-commercial, and by any means.
+*
+* In jurisdictions that recognize copyright laws, the author or authors of this
+* software dedicate any and all copyright interest in the software to the public
+* domain. We make this dedication for the benefit of the public at large and to
+* the detriment of our heirs and successors. We intend this dedication to be an
+* overt act of relinquishment in perpetuity of all present and future rights to
+* this software under copyright law.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*
+**********************************************************************************************/
+
+#ifndef GIF_H
+#define GIF_H
+
+#include <stdio.h> // Required for: FILE
+#include <stdint.h> // Required for for integer typedefs
+
+//#define GIF_STATIC
+#ifdef GIF_STATIC
+ #define GIFDEF static // Functions just visible to module including this file
+#else
+ #ifdef __cplusplus
+ #define GIFDEF extern "C" // Functions visible from other files (no name mangling of functions in C++)
+ #else
+ #define GIFDEF extern // Functions visible from other files
+ #endif
+#endif
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+//#define MAX_RESOURCES_SUPPORTED 256
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+typedef struct GifWriter {
+ FILE *f;
+ uint8_t *oldImage;
+ bool firstFrame;
+} GifWriter;
+
+//----------------------------------------------------------------------------------
+// Global variables
+//----------------------------------------------------------------------------------
+//...
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+
+// NOTE: By default use bitDepth = 8, dither = false
+GIFDEF bool GifBegin(GifWriter *writer, const char *filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth, bool dither);
+GIFDEF bool GifWriteFrame(GifWriter *writer, const uint8_t *image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth, bool dither);
+GIFDEF bool GifEnd(GifWriter *writer);
+
+#endif // GIF_H
+
+
+/***********************************************************************************
+*
+ * GIF IMPLEMENTATION
+*
+************************************************************************************/
+
+#if defined(GIF_IMPLEMENTATION)
+
+#include <stdio.h> // Required for: FILE, fopen(), fclose()
+#include <string.h> // Required for: memcpy()
+#include <stdint.h> // Required for for integer typedefs
+
+// Define these macros to hook into a custom memory allocator.
+// GIF_TEMP_MALLOC and GIF_TEMP_FREE will only be called in stack fashion - frees in the reverse order of mallocs
+// and any temp memory allocated by a function will be freed before it exits.
+#if !defined(GIF_TEMP_MALLOC)
+ #include <stdlib.h>
+
+ #define GIF_TEMP_MALLOC malloc
+ #define GIF_TEMP_FREE free
+#endif
+
+// Check if custom malloc/free functions defined, if not, using standard ones
+// GIF_MALLOC and GIF_FREE are used only by GifBegin and GifEnd respectively,
+// to allocate a buffer the size of the image, which is used to find changed pixels for delta-encoding.
+#if !defined(GIF_MALLOC)
+ #include <stdlib.h> // Required for: malloc(), free()
+
+ #define GIF_MALLOC(size) malloc(size)
+ #define GIF_FREE(ptr) free(ptr)
+#endif
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+#define GIFMIN(a, b) (((a)<(b))?(a):(b))
+#define GIFMAX(a, b) (((a)>(b))?(a):(b))
+#define GIFABS(x) ((x)<0?-(x):(x))
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+
+//Gif palette structure
+typedef struct GifPalette {
+ int bitDepth;
+
+ uint8_t r[256];
+ uint8_t g[256];
+ uint8_t b[256];
+
+ // k-d tree over RGB space, organized in heap fashion
+ // i.e. left child of node i is node i*2, right child is node i*2 + 1
+ // nodes 256-511 are implicitly the leaves, containing a color
+ uint8_t treeSplitElt[255];
+ uint8_t treeSplit[255];
+} GifPalette;
+
+
+// Simple structure to write out the LZW-compressed
+// portion of the imageone bit at a time
+typedef struct GifBitStatus {
+ uint8_t bitIndex; // how many bits in the partial byte written so far
+ uint8_t byte; // current partial byte
+
+ uint32_t chunkIndex;
+ uint8_t chunk[256]; // bytes are written in here until we have 256 of them, then written to the file
+} GifBitStatus;
+
+// The LZW dictionary is a 256-ary tree constructed
+// as the file is encoded, this is one node
+typedef struct GifLzwNode {
+ uint16_t m_next[256];
+} GifLzwNode;
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+const int kGifTransIndex = 0;
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Declaration
+//----------------------------------------------------------------------------------
+static void GifGetClosestPaletteColor(GifPalette *pPal, int r, int g, int b, int *bestInd, int *bestDiff, int treeRoot);
+static void GifSwapPixels(uint8_t *image, int pixA, int pixB);
+static int GifPartition(uint8_t *image, const int left, const int right, const int elt, int pivotIndex);
+static void GifPartitionByMedian(uint8_t *image, int left, int right, int com, int neededCenter);
+static void GifSplitPalette(uint8_t *image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist, int treeNode, bool buildForDither, GifPalette *pal);
+static int GifPickChangedPixels(const uint8_t *lastFrame, uint8_t *frame, int numPixels);
+static void GifMakePalette(const uint8_t *lastFrame, const uint8_t *nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette *pPal);
+static void GifDitherImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal);
+static void GifThresholdImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal);
+static void GifWriteBit(GifBitStatus *stat, uint32_t bit);
+static void GifWriteChunk(FILE *f, GifBitStatus *stat);
+static void GifWriteCode(FILE *f, GifBitStatus *stat, uint32_t code, uint32_t length);
+static void GifWritePalette(const GifPalette *pPal, FILE *f);
+static void GifWriteLzwImage(FILE *f, uint8_t *image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette *pPal);
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition
+//----------------------------------------------------------------------------------
+
+// Creates a gif file.
+// The input GIFWriter is assumed to be uninitialized.
+// The delay value is the time between frames in hundredths of a second - note that not all viewers pay much attention to this value.
+GIFDEF bool GifBegin(GifWriter *writer, const char *filename, uint32_t width, uint32_t height, uint32_t delay, int32_t bitDepth, bool dither)
+{
+#if _MSC_VER >= 1400
+ writer->f = 0;
+ fopen_s(&writer->f, filename, "wb");
+#else
+ writer->f = fopen(filename, "wb");
+#endif
+ if (!writer->f) return false;
+
+ writer->firstFrame = true;
+
+ // allocate
+ writer->oldImage = (uint8_t*)GIF_MALLOC(width*height*4);
+
+ fputs("GIF89a", writer->f);
+
+ // screen descriptor
+ fputc(width & 0xff, writer->f);
+ fputc((width >> 8) & 0xff, writer->f);
+ fputc(height & 0xff, writer->f);
+ fputc((height >> 8) & 0xff, writer->f);
+
+ fputc(0xf0, writer->f); // there is an unsorted global color table of 2 entries
+ fputc(0, writer->f); // background color
+ fputc(0, writer->f); // pixels are square (we need to specify this because it's 1989)
+
+ // now the "global" palette (really just a dummy palette)
+ // color 0: black
+ fputc(0, writer->f);
+ fputc(0, writer->f);
+ fputc(0, writer->f);
+ // color 1: also black
+ fputc(0, writer->f);
+ fputc(0, writer->f);
+ fputc(0, writer->f);
+
+ if (delay != 0)
+ {
+ // animation header
+ fputc(0x21, writer->f); // extension
+ fputc(0xff, writer->f); // application specific
+ fputc(11, writer->f); // length 11
+ fputs("NETSCAPE2.0", writer->f); // yes, really
+ fputc(3, writer->f); // 3 bytes of NETSCAPE2.0 data
+
+ fputc(1, writer->f); // JUST BECAUSE
+ fputc(0, writer->f); // loop infinitely (byte 0)
+ fputc(0, writer->f); // loop infinitely (byte 1)
+
+ fputc(0, writer->f); // block terminator
+ }
+
+ return true;
+}
+
+// Writes out a new frame to a GIF in progress.
+// The GIFWriter should have been created by GIFBegin.
+// AFAIK, it is legal to use different bit depths for different frames of an image -
+// this may be handy to save bits in animations that don't change much.
+GIFDEF bool GifWriteFrame(GifWriter *writer, const uint8_t *image, uint32_t width, uint32_t height, uint32_t delay, int bitDepth, bool dither)
+{
+ if (!writer->f) return false;
+
+ const uint8_t *oldImage = writer->firstFrame? NULL : writer->oldImage;
+ writer->firstFrame = false;
+
+ GifPalette pal;
+ GifMakePalette((dither? NULL : oldImage), image, width, height, bitDepth, dither, &pal);
+
+ if (dither)
+ GifDitherImage(oldImage, image, writer->oldImage, width, height, &pal);
+ else
+ GifThresholdImage(oldImage, image, writer->oldImage, width, height, &pal);
+
+ GifWriteLzwImage(writer->f, writer->oldImage, 0, 0, width, height, delay, &pal);
+
+ return true;
+}
+
+// Writes the EOF code, closes the file handle, and frees temp memory used by a GIF.
+// Many if not most viewers will still display a GIF properly if the EOF code is missing,
+// but it's still a good idea to write it out.
+GIFDEF bool GifEnd(GifWriter *writer)
+{
+ if (!writer->f) return false;
+
+ fputc(0x3b, writer->f); // end of file
+ fclose(writer->f);
+ GIF_FREE(writer->oldImage);
+
+ writer->f = NULL;
+ writer->oldImage = NULL;
+
+ return true;
+}
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
+// walks the k-d tree to pick the palette entry for a desired color.
+// Takes as in/out parameters the current best color and its error -
+// only changes them if it finds a better color in its subtree.
+// this is the major hotspot in the code at the moment.
+static void GifGetClosestPaletteColor(GifPalette *pPal, int r, int g, int b, int *bestInd, int *bestDiff, int treeRoot)
+{
+ // base case, reached the bottom of the tree
+ if (treeRoot > (1<<pPal->bitDepth)-1)
+ {
+ int ind = treeRoot-(1<<pPal->bitDepth);
+ if (ind == kGifTransIndex) return;
+
+ // check whether this color is better than the current winner
+ int r_err = r - ((int32_t)pPal->r[ind]);
+ int g_err = g - ((int32_t)pPal->g[ind]);
+ int b_err = b - ((int32_t)pPal->b[ind]);
+ int diff = GIFABS(r_err)+GIFABS(g_err)+GIFABS(b_err);
+
+ if (diff < *bestDiff)
+ {
+ *bestInd = ind;
+ *bestDiff = diff;
+ }
+
+ return;
+ }
+
+ // take the appropriate color (r, g, or b) for this node of the k-d tree
+ int comps[3]; comps[0] = r; comps[1] = g; comps[2] = b;
+ int splitComp = comps[pPal->treeSplitElt[treeRoot]];
+
+ int splitPos = pPal->treeSplit[treeRoot];
+ if (splitPos > splitComp)
+ {
+ // check the left subtree
+ GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2);
+
+ if (*bestDiff > (splitPos - splitComp))
+ {
+ // cannot prove there's not a better value in the right subtree, check that too
+ GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2 + 1);
+ }
+ }
+ else
+ {
+ GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2 + 1);
+
+ if (*bestDiff > splitComp - splitPos)
+ {
+ GifGetClosestPaletteColor(pPal, r, g, b, bestInd, bestDiff, treeRoot*2);
+ }
+ }
+}
+
+static void GifSwapPixels(uint8_t *image, int pixA, int pixB)
+{
+ uint8_t rA = image[pixA*4];
+ uint8_t gA = image[pixA*4 + 1];
+ uint8_t bA = image[pixA*4+2];
+ uint8_t aA = image[pixA*4+3];
+
+ uint8_t rB = image[pixB*4];
+ uint8_t gB = image[pixB*4 + 1];
+ uint8_t bB = image[pixB*4+2];
+ uint8_t aB = image[pixA*4+3];
+
+ image[pixA*4] = rB;
+ image[pixA*4 + 1] = gB;
+ image[pixA*4+2] = bB;
+ image[pixA*4+3] = aB;
+
+ image[pixB*4] = rA;
+ image[pixB*4 + 1] = gA;
+ image[pixB*4+2] = bA;
+ image[pixB*4+3] = aA;
+}
+
+// just the partition operation from quicksort
+static int GifPartition(uint8_t *image, const int left, const int right, const int elt, int pivotIndex)
+{
+ const int pivotValue = image[(pivotIndex)*4+elt];
+ GifSwapPixels(image, pivotIndex, right-1);
+ int storeIndex = left;
+ bool split = 0;
+ for (int ii=left; ii<right-1; ++ii)
+ {
+ int arrayVal = image[ii*4+elt];
+ if (arrayVal < pivotValue)
+ {
+ GifSwapPixels(image, ii, storeIndex);
+ ++storeIndex;
+ }
+ else if (arrayVal == pivotValue)
+ {
+ if (split)
+ {
+ GifSwapPixels(image, ii, storeIndex);
+ ++storeIndex;
+ }
+ split = !split;
+ }
+ }
+ GifSwapPixels(image, storeIndex, right-1);
+ return storeIndex;
+}
+
+// Perform an incomplete sort, finding all elements above and below the desired median
+static void GifPartitionByMedian(uint8_t *image, int left, int right, int com, int neededCenter)
+{
+ if (left < right-1)
+ {
+ int pivotIndex = left + (right-left)/2;
+
+ pivotIndex = GifPartition(image, left, right, com, pivotIndex);
+
+ // Only "sort" the section of the array that contains the median
+ if (pivotIndex > neededCenter)
+ GifPartitionByMedian(image, left, pivotIndex, com, neededCenter);
+
+ if (pivotIndex < neededCenter)
+ GifPartitionByMedian(image, pivotIndex + 1, right, com, neededCenter);
+ }
+}
+
+// Builds a palette by creating a balanced k-d tree of all pixels in the image
+static void GifSplitPalette(uint8_t *image, int numPixels, int firstElt, int lastElt, int splitElt, int splitDist,
+ int treeNode, bool buildForDither, GifPalette *pal)
+{
+ if (lastElt <= firstElt || numPixels == 0)
+ return;
+
+ // base case, bottom of the tree
+ if (lastElt == firstElt + 1)
+ {
+ if (buildForDither)
+ {
+ // Dithering needs at least one color as dark as anything
+ // in the image and at least one brightest color -
+ // otherwise it builds up error and produces strange artifacts
+ if (firstElt == 1)
+ {
+ // special case: the darkest color in the image
+ uint32_t r=255, g=255, b=255;
+ for (int ii=0; ii<numPixels; ++ii)
+ {
+ r = GIFMIN(r, image[ii*4+0]);
+ g = GIFMIN(g, image[ii*4 + 1]);
+ b = GIFMIN(b, image[ii*4+2]);
+ }
+
+ pal->r[firstElt] = r;
+ pal->g[firstElt] = g;
+ pal->b[firstElt] = b;
+
+ return;
+ }
+
+ if (firstElt == (1 << pal->bitDepth)-1)
+ {
+ // special case: the lightest color in the image
+ uint32_t r=0, g=0, b=0;
+ for (int ii=0; ii<numPixels; ++ii)
+ {
+ r = GIFMAX(r, image[ii*4+0]);
+ g = GIFMAX(g, image[ii*4 + 1]);
+ b = GIFMAX(b, image[ii*4+2]);
+ }
+
+ pal->r[firstElt] = r;
+ pal->g[firstElt] = g;
+ pal->b[firstElt] = b;
+
+ return;
+ }
+ }
+
+ // otherwise, take the average of all colors in this subcube
+ uint64_t r=0, g=0, b=0;
+ for (int ii=0; ii<numPixels; ++ii)
+ {
+ r += image[ii*4+0];
+ g += image[ii*4 + 1];
+ b += image[ii*4+2];
+ }
+
+ r += numPixels / 2; // round to nearest
+ g += numPixels / 2;
+ b += numPixels / 2;
+
+ r /= numPixels;
+ g /= numPixels;
+ b /= numPixels;
+
+ pal->r[firstElt] = (uint8_t)r;
+ pal->g[firstElt] = (uint8_t)g;
+ pal->b[firstElt] = (uint8_t)b;
+
+ return;
+ }
+
+ // Find the axis with the largest range
+ int minR = 255, maxR = 0;
+ int minG = 255, maxG = 0;
+ int minB = 255, maxB = 0;
+ for (int ii=0; ii<numPixels; ++ii)
+ {
+ int r = image[ii*4+0];
+ int g = image[ii*4 + 1];
+ int b = image[ii*4+2];
+
+ if (r > maxR) maxR = r;
+ if (r < minR) minR = r;
+
+ if (g > maxG) maxG = g;
+ if (g < minG) minG = g;
+
+ if (b > maxB) maxB = b;
+ if (b < minB) minB = b;
+ }
+
+ int rRange = maxR - minR;
+ int gRange = maxG - minG;
+ int bRange = maxB - minB;
+
+ // and split along that axis. (incidentally, this means this isn't a "proper" k-d tree but I don't know what else to call it)
+ int splitCom = 1;
+ if (bRange > gRange) splitCom = 2;
+ if (rRange > bRange && rRange > gRange) splitCom = 0;
+
+ int subPixelsA = numPixels *(splitElt - firstElt) / (lastElt - firstElt);
+ int subPixelsB = numPixels-subPixelsA;
+
+ GifPartitionByMedian(image, 0, numPixels, splitCom, subPixelsA);
+
+ pal->treeSplitElt[treeNode] = splitCom;
+ pal->treeSplit[treeNode] = image[subPixelsA*4+splitCom];
+
+ GifSplitPalette(image, subPixelsA, firstElt, splitElt, splitElt-splitDist, splitDist/2, treeNode*2, buildForDither, pal);
+ GifSplitPalette(image+subPixelsA*4, subPixelsB, splitElt, lastElt, splitElt+splitDist, splitDist/2, treeNode*2 + 1, buildForDither, pal);
+}
+
+// Finds all pixels that have changed from the previous image and
+// moves them to the fromt of th buffer.
+// This allows us to build a palette optimized for the colors of the
+// changed pixels only.
+static int GifPickChangedPixels(const uint8_t *lastFrame, uint8_t *frame, int numPixels)
+{
+ int numChanged = 0;
+ uint8_t *writeIter = frame;
+
+ for (int ii=0; ii<numPixels; ++ii)
+ {
+ if (lastFrame[0] != frame[0] ||
+ lastFrame[1] != frame[1] ||
+ lastFrame[2] != frame[2])
+ {
+ writeIter[0] = frame[0];
+ writeIter[1] = frame[1];
+ writeIter[2] = frame[2];
+ ++numChanged;
+ writeIter += 4;
+ }
+ lastFrame += 4;
+ frame += 4;
+ }
+
+ return numChanged;
+}
+
+// Creates a palette by placing all the image pixels in a k-d tree and then averaging the blocks at the bottom.
+// This is known as the "modified median split" technique
+static void GifMakePalette(const uint8_t *lastFrame, const uint8_t *nextFrame, uint32_t width, uint32_t height, int bitDepth, bool buildForDither, GifPalette *pPal)
+{
+ pPal->bitDepth = bitDepth;
+
+ // SplitPalette is destructive (it sorts the pixels by color) so
+ // we must create a copy of the image for it to destroy
+ int imageSize = width*height*4*sizeof(uint8_t);
+ uint8_t *destroyableImage = (uint8_t*)GIF_TEMP_MALLOC(imageSize);
+ memcpy(destroyableImage, nextFrame, imageSize);
+
+ int numPixels = width*height;
+ if (lastFrame)
+ numPixels = GifPickChangedPixels(lastFrame, destroyableImage, numPixels);
+
+ const int lastElt = 1 << bitDepth;
+ const int splitElt = lastElt/2;
+ const int splitDist = splitElt/2;
+
+ GifSplitPalette(destroyableImage, numPixels, 1, lastElt, splitElt, splitDist, 1, buildForDither, pPal);
+
+ GIF_TEMP_FREE(destroyableImage);
+
+ // add the bottom node for the transparency index
+ pPal->treeSplit[1 << (bitDepth-1)] = 0;
+ pPal->treeSplitElt[1 << (bitDepth-1)] = 0;
+
+ pPal->r[0] = pPal->g[0] = pPal->b[0] = 0;
+}
+
+// Implements Floyd-Steinberg dithering, writes palette value to alpha
+static void GifDitherImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal)
+{
+ int numPixels = width*height;
+
+ // quantPixels initially holds color*256 for all pixels
+ // The extra 8 bits of precision allow for sub-single-color error values
+ // to be propagated
+ int32_t *quantPixels = (int32_t*)GIF_TEMP_MALLOC(sizeof(int32_t)*numPixels*4);
+
+ for (int ii=0; ii<numPixels*4; ++ii)
+ {
+ uint8_t pix = nextFrame[ii];
+ int32_t pix16 = (int32_t)pix*256;
+ quantPixels[ii] = pix16;
+ }
+
+ for (uint32_t yy=0; yy<height; ++yy)
+ {
+ for (uint32_t xx=0; xx<width; ++xx)
+ {
+ int32_t *nextPix = quantPixels + 4*(yy*width+xx);
+ const uint8_t *lastPix = lastFrame? lastFrame + 4*(yy*width+xx) : NULL;
+
+ // Compute the colors we want (rounding to nearest)
+ int32_t rr = (nextPix[0] + 127) / 256;
+ int32_t gg = (nextPix[1] + 127) / 256;
+ int32_t bb = (nextPix[2] + 127) / 256;
+
+ // if it happens that we want the color from last frame, then just write out
+ // a transparent pixel
+ if (lastFrame &&
+ lastPix[0] == rr &&
+ lastPix[1] == gg &&
+ lastPix[2] == bb)
+ {
+ nextPix[0] = rr;
+ nextPix[1] = gg;
+ nextPix[2] = bb;
+ nextPix[3] = kGifTransIndex;
+ continue;
+ }
+
+ int32_t bestDiff = 1000000;
+ int32_t bestInd = kGifTransIndex;
+
+ // Search the palete
+ GifGetClosestPaletteColor(pPal, rr, gg, bb, &bestInd, &bestDiff, 1);
+
+ // Write the result to the temp buffer
+ int32_t r_err = nextPix[0] - (int32_t)(pPal->r[bestInd])*256;
+ int32_t g_err = nextPix[1] - (int32_t)(pPal->g[bestInd])*256;
+ int32_t b_err = nextPix[2] - (int32_t)(pPal->b[bestInd])*256;
+
+ nextPix[0] = pPal->r[bestInd];
+ nextPix[1] = pPal->g[bestInd];
+ nextPix[2] = pPal->b[bestInd];
+ nextPix[3] = bestInd;
+
+ // Propagate the error to the four adjacent locations
+ // that we haven't touched yet
+ int quantloc_7 = (yy*width+xx + 1);
+ int quantloc_3 = (yy*width+width+xx-1);
+ int quantloc_5 = (yy*width+width+xx);
+ int quantloc_1 = (yy*width+width+xx + 1);
+
+ if (quantloc_7 < numPixels)
+ {
+ int32_t *pix7 = quantPixels+4*quantloc_7;
+ pix7[0] += GIFMAX(-pix7[0], r_err*7 / 16);
+ pix7[1] += GIFMAX(-pix7[1], g_err*7 / 16);
+ pix7[2] += GIFMAX(-pix7[2], b_err*7 / 16);
+ }
+
+ if (quantloc_3 < numPixels)
+ {
+ int32_t *pix3 = quantPixels+4*quantloc_3;
+ pix3[0] += GIFMAX(-pix3[0], r_err*3 / 16);
+ pix3[1] += GIFMAX(-pix3[1], g_err*3 / 16);
+ pix3[2] += GIFMAX(-pix3[2], b_err*3 / 16);
+ }
+
+ if (quantloc_5 < numPixels)
+ {
+ int32_t *pix5 = quantPixels+4*quantloc_5;
+ pix5[0] += GIFMAX(-pix5[0], r_err*5 / 16);
+ pix5[1] += GIFMAX(-pix5[1], g_err*5 / 16);
+ pix5[2] += GIFMAX(-pix5[2], b_err*5 / 16);
+ }
+
+ if (quantloc_1 < numPixels)
+ {
+ int32_t *pix1 = quantPixels+4*quantloc_1;
+ pix1[0] += GIFMAX(-pix1[0], r_err / 16);
+ pix1[1] += GIFMAX(-pix1[1], g_err / 16);
+ pix1[2] += GIFMAX(-pix1[2], b_err / 16);
+ }
+ }
+ }
+
+ // Copy the palettized result to the output buffer
+ for (int ii=0; ii<numPixels*4; ++ii)
+ {
+ outFrame[ii] = quantPixels[ii];
+ }
+
+ GIF_TEMP_FREE(quantPixels);
+}
+
+// Picks palette colors for the image using simple thresholding, no dithering
+static void GifThresholdImage(const uint8_t *lastFrame, const uint8_t *nextFrame, uint8_t *outFrame, uint32_t width, uint32_t height, GifPalette *pPal)
+{
+ uint32_t numPixels = width*height;
+ for (uint32_t ii=0; ii<numPixels; ++ii)
+ {
+ // if a previous color is available, and it matches the current color,
+ // set the pixel to transparent
+ if (lastFrame &&
+ lastFrame[0] == nextFrame[0] &&
+ lastFrame[1] == nextFrame[1] &&
+ lastFrame[2] == nextFrame[2])
+ {
+ outFrame[0] = lastFrame[0];
+ outFrame[1] = lastFrame[1];
+ outFrame[2] = lastFrame[2];
+ outFrame[3] = kGifTransIndex;
+ }
+ else
+ {
+ // palettize the pixel
+ int32_t bestDiff = 1000000;
+ int32_t bestInd = 1;
+ GifGetClosestPaletteColor(pPal, nextFrame[0], nextFrame[1], nextFrame[2], &bestInd, &bestDiff, 1);
+
+ // Write the resulting color to the output buffer
+ outFrame[0] = pPal->r[bestInd];
+ outFrame[1] = pPal->g[bestInd];
+ outFrame[2] = pPal->b[bestInd];
+ outFrame[3] = bestInd;
+ }
+
+ if (lastFrame) lastFrame += 4;
+ outFrame += 4;
+ nextFrame += 4;
+ }
+}
+
+
+// insert a single bit
+static void GifWriteBit(GifBitStatus *stat, uint32_t bit)
+{
+ bit = bit & 1;
+ bit = bit << stat->bitIndex;
+ stat->byte |= bit;
+
+ ++stat->bitIndex;
+ if (stat->bitIndex > 7)
+ {
+ // move the newly-finished byte to the chunk buffer
+ stat->chunk[stat->chunkIndex++] = stat->byte;
+ // and start a new byte
+ stat->bitIndex = 0;
+ stat->byte = 0;
+ }
+}
+
+// write all bytes so far to the file
+static void GifWriteChunk(FILE *f, GifBitStatus *stat)
+{
+ fputc(stat->chunkIndex, f);
+ fwrite(stat->chunk, 1, stat->chunkIndex, f);
+
+ stat->bitIndex = 0;
+ stat->byte = 0;
+ stat->chunkIndex = 0;
+}
+
+static void GifWriteCode(FILE *f, GifBitStatus *stat, uint32_t code, uint32_t length)
+{
+ for (uint32_t ii=0; ii<length; ++ii)
+ {
+ GifWriteBit(stat, code);
+ code = code >> 1;
+
+ if (stat->chunkIndex == 255)
+ {
+ GifWriteChunk(f, stat);
+ }
+ }
+}
+
+// write a 256-color (8-bit) image palette to the file
+static void GifWritePalette(const GifPalette *pPal, FILE *f)
+{
+ fputc(0, f); // first color: transparency
+ fputc(0, f);
+ fputc(0, f);
+
+ for (int ii=1; ii<(1 << pPal->bitDepth); ++ii)
+ {
+ uint32_t r = pPal->r[ii];
+ uint32_t g = pPal->g[ii];
+ uint32_t b = pPal->b[ii];
+
+ fputc(r, f);
+ fputc(g, f);
+ fputc(b, f);
+ }
+}
+
+// write the image header, LZW-compress and write out the image
+static void GifWriteLzwImage(FILE *f, uint8_t *image, uint32_t left, uint32_t top, uint32_t width, uint32_t height, uint32_t delay, GifPalette *pPal)
+{
+ // graphics control extension
+ fputc(0x21, f);
+ fputc(0xf9, f);
+ fputc(0x04, f);
+ fputc(0x05, f); // leave prev frame in place, this frame has transparency
+ fputc(delay & 0xff, f);
+ fputc((delay >> 8) & 0xff, f);
+ fputc(kGifTransIndex, f); // transparent color index
+ fputc(0, f);
+
+ fputc(0x2c, f); // image descriptor block
+
+ fputc(left & 0xff, f); // corner of image in canvas space
+ fputc((left >> 8) & 0xff, f);
+ fputc(top & 0xff, f);
+ fputc((top >> 8) & 0xff, f);
+
+ fputc(width & 0xff, f); // width and height of image
+ fputc((width >> 8) & 0xff, f);
+ fputc(height & 0xff, f);
+ fputc((height >> 8) & 0xff, f);
+
+ //fputc(0, f); // no local color table, no transparency
+ //fputc(0x80, f); // no local color table, but transparency
+
+ fputc(0x80 + pPal->bitDepth-1, f); // local color table present, 2 ^ bitDepth entries
+ GifWritePalette(pPal, f);
+
+ const int minCodeSize = pPal->bitDepth;
+ const uint32_t clearCode = 1 << pPal->bitDepth;
+
+ fputc(minCodeSize, f); // min code size 8 bits
+
+ GifLzwNode *codetree = (GifLzwNode *)GIF_TEMP_MALLOC(sizeof(GifLzwNode)*4096);
+
+ memset(codetree, 0, sizeof(GifLzwNode)*4096);
+ int32_t curCode = -1;
+ uint32_t codeSize = minCodeSize + 1;
+ uint32_t maxCode = clearCode + 1;
+
+ GifBitStatus stat;
+ stat.byte = 0;
+ stat.bitIndex = 0;
+ stat.chunkIndex = 0;
+
+ GifWriteCode(f, &stat, clearCode, codeSize); // start with a fresh LZW dictionary
+
+ for (uint32_t yy=0; yy<height; ++yy)
+ {
+ for (uint32_t xx=0; xx<width; ++xx)
+ {
+ uint8_t nextValue = image[(yy*width+xx)*4+3];
+
+ // "loser mode" - no compression, every single code is followed immediately by a clear
+ //WriteCode(f, stat, nextValue, codeSize);
+ //WriteCode(f, stat, 256, codeSize);
+
+ if (curCode < 0)
+ {
+ // first value in a new run
+ curCode = nextValue;
+ }
+ else if (codetree[curCode].m_next[nextValue])
+ {
+ // current run already in the dictionary
+ curCode = codetree[curCode].m_next[nextValue];
+ }
+ else
+ {
+ // finish the current run, write a code
+ GifWriteCode(f, &stat, curCode, codeSize);
+
+ // insert the new run into the dictionary
+ codetree[curCode].m_next[nextValue] = ++maxCode;
+
+ if (maxCode >= (1ul << codeSize))
+ {
+ // dictionary entry count has broken a size barrier,
+ // we need more bits for codes
+ codeSize++;
+ }
+ if (maxCode == 4095)
+ {
+ // the dictionary is full, clear it out and begin anew
+ GifWriteCode(f, &stat, clearCode, codeSize); // clear tree
+
+ memset(codetree, 0, sizeof(GifLzwNode)*4096);
+ curCode = -1;
+ codeSize = minCodeSize + 1;
+ maxCode = clearCode + 1;
+ }
+
+ curCode = nextValue;
+ }
+ }
+ }
+
+ // compression footer
+ GifWriteCode(f, &stat, curCode, codeSize);
+ GifWriteCode(f, &stat, clearCode, codeSize);
+ GifWriteCode(f, &stat, clearCode + 1, minCodeSize + 1);
+
+ // write out the last partial chunk
+ while (stat.bitIndex) GifWriteBit(&stat, 0);
+ if (stat.chunkIndex) GifWriteChunk(f, &stat);
+
+ fputc(0, f); // image block terminator
+
+ GIF_TEMP_FREE(codetree);
+}
+
+#endif // GIF_IMPLEMENTATION
diff --git a/src/external/glfw3/lib/win32/glfw3.lib b/src/external/glfw3/lib/win32/glfw3.lib
new file mode 100644
index 00000000..741756ab
--- /dev/null
+++ b/src/external/glfw3/lib/win32/glfw3.lib
Binary files differ
diff --git a/src/external/lua/include/lauxlib.h b/src/external/lua/include/lauxlib.h
deleted file mode 100644
index ddb7c228..00000000
--- a/src/external/lua/include/lauxlib.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
-** $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
deleted file mode 100644
index f78899fc..00000000
--- a/src/external/lua/include/lua.h
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
-** $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
deleted file mode 100644
index ec417f59..00000000
--- a/src/external/lua/include/lua.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-// 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
deleted file mode 100644
index 867e9cb1..00000000
--- a/src/external/lua/include/luaconf.h
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
-** $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
deleted file mode 100644
index 5165c0fb..00000000
--- a/src/external/lua/include/lualib.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-** $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
deleted file mode 100644
index e51c0c80..00000000
--- a/src/external/lua/lib/liblua53.a
+++ /dev/null
Binary files differ
diff --git a/src/external/lua/lib/liblua53dll.a b/src/external/lua/lib/liblua53dll.a
deleted file mode 100644
index 32646db3..00000000
--- a/src/external/lua/lib/liblua53dll.a
+++ /dev/null
Binary files differ
diff --git a/src/external/openal_soft/include/AL/alext.h b/src/external/openal_soft/include/AL/alext.h
index 0090c804..50ad10ec 100644
--- a/src/external/openal_soft/include/AL/alext.h
+++ b/src/external/openal_soft/include/AL/alext.h
@@ -436,6 +436,18 @@ ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCi
#define AL_GAIN_LIMIT_SOFT 0x200E
#endif
+#ifndef AL_SOFT_source_resampler
+#define AL_SOFT_source_resampler
+#define AL_NUM_RESAMPLERS_SOFT 0x1210
+#define AL_DEFAULT_RESAMPLER_SOFT 0x1211
+#define AL_SOURCE_RESAMPLER_SOFT 0x1212
+#define AL_RESAMPLER_NAME_SOFT 0x1213
+typedef const ALchar* (AL_APIENTRY*LPALGETSTRINGISOFT)(ALenum pname, ALsizei index);
+#ifdef AL_ALEXT_PROTOTYPES
+AL_API const ALchar* AL_APIENTRY alGetStringiSOFT(ALenum pname, ALsizei index);
+#endif
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/src/external/openal_soft/lib/android/libopenal.so b/src/external/openal_soft/lib/android/libopenal.so
new file mode 100644
index 00000000..e384d9ad
--- /dev/null
+++ b/src/external/openal_soft/lib/android/libopenal.so
Binary files differ
diff --git a/src/external/pthread/COPYING b/src/external/pthread/COPYING
deleted file mode 100644
index 5cfea0d0..00000000
--- a/src/external/pthread/COPYING
+++ /dev/null
@@ -1,150 +0,0 @@
- pthreads-win32 - a POSIX threads library for Microsoft Windows
-
-
-This file is Copyrighted
-------------------------
-
- This file is covered under the following Copyright:
-
- Copyright (C) 2001,2006 Ross P. Johnson
- All rights reserved.
-
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-Pthreads-win32 is covered by the GNU Lesser General Public License
-------------------------------------------------------------------
-
- Pthreads-win32 is open software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public License
- as published by the Free Software Foundation version 2.1 of the
- License.
-
- Pthreads-win32 is several binary link libraries, several modules,
- associated interface definition files and scripts used to control
- its compilation and installation.
-
- Pthreads-win32 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- A copy of the GNU Lesser General Public License is distributed with
- pthreads-win32 under the filename:
-
- COPYING.LIB
-
- You should have received a copy of the version 2.1 GNU Lesser General
- Public License with pthreads-win32; if not, write to:
-
- Free Software Foundation, Inc.
- 59 Temple Place
- Suite 330
- Boston, MA 02111-1307
- USA
-
- The contact addresses for pthreads-win32 is as follows:
-
- Web: http://sources.redhat.com/pthreads-win32
- Email: Ross Johnson
- Please use: Firstname.Lastname@homemail.com.au
-
-
-
-Pthreads-win32 copyrights and exception files
----------------------------------------------
-
- With the exception of the files listed below, Pthreads-win32
- is covered under the following GNU Lesser General Public License
- Copyrights:
-
- Pthreads-win32 - POSIX Threads Library for Win32
- Copyright(C) 1998 John E. Bossom
- Copyright(C) 1999,2006 Pthreads-win32 contributors
-
- The current list of contributors is contained
- in the file CONTRIBUTORS included with the source
- code distribution. The current list of CONTRIBUTORS
- can also be seen at the following WWW location:
- http://sources.redhat.com/pthreads-win32/contributors.html
-
- Contact Email: Ross Johnson
- Please use: Firstname.Lastname@homemail.com.au
-
- These files are not covered under one of the Copyrights listed above:
-
- COPYING
- COPYING.LIB
- tests/rwlock7.c
-
- This file, COPYING, is distributed under the Copyright found at the
- top of this file. It is important to note that you may distribute
- verbatim copies of this file but you may not modify this file.
-
- The file COPYING.LIB, which contains a copy of the version 2.1
- GNU Lesser General Public License, is itself copyrighted by the
- Free Software Foundation, Inc. Please note that the Free Software
- Foundation, Inc. does NOT have a copyright over Pthreads-win32,
- only the COPYING.LIB that is supplied with pthreads-win32.
-
- The file tests/rwlock7.c is derived from code written by
- Dave Butenhof for his book 'Programming With POSIX(R) Threads'.
- The original code was obtained by free download from his website
- http://home.earthlink.net/~anneart/family/Threads/source.html
- and did not contain a copyright or author notice. It is assumed to
- be freely distributable.
-
- In all cases one may use and distribute these exception files freely.
- And because one may freely distribute the LGPL covered files, the
- entire pthreads-win32 source may be freely used and distributed.
-
-
-
-General Copyleft and License info
----------------------------------
-
- For general information on Copylefts, see:
-
- http://www.gnu.org/copyleft/
-
- For information on GNU Lesser General Public Licenses, see:
-
- http://www.gnu.org/copyleft/lesser.html
- http://www.gnu.org/copyleft/lesser.txt
-
-
-Why pthreads-win32 did not use the GNU General Public License
--------------------------------------------------------------
-
- The goal of the pthreads-win32 project has been to
- provide a quality and complete implementation of the POSIX
- threads API for Microsoft Windows within the limits imposed
- by virtue of it being a stand-alone library and not
- linked directly to other POSIX compliant libraries. For
- example, some functions and features, such as those based
- on POSIX signals, are missing.
-
- Pthreads-win32 is a library, available in several different
- versions depending on supported compilers, and may be used
- as a dynamically linked module or a statically linked set of
- binary modules. It is not an application on it's own.
-
- It was fully intended that pthreads-win32 be usable with
- commercial software not covered by either the GPL or the LGPL
- licenses. Pthreads-win32 has many contributors to it's
- code base, many of whom have done so because they have
- used the library in commercial or proprietry software
- projects.
-
- Releasing pthreads-win32 under the LGPL ensures that the
- library can be used widely, while at the same time ensures
- that bug fixes and improvements to the pthreads-win32 code
- itself is returned to benefit all current and future users
- of the library.
-
- Although pthreads-win32 makes it possible for applications
- that use POSIX threads to be ported to Win32 platforms, the
- broader goal of the project is to encourage the use of open
- standards, and in particular, to make it just a little easier
- for developers writing Win32 applications to consider
- widening the potential market for their products.
diff --git a/src/external/pthread/include/pthread.h b/src/external/pthread/include/pthread.h
deleted file mode 100644
index b4072f72..00000000
--- a/src/external/pthread/include/pthread.h
+++ /dev/null
@@ -1,1368 +0,0 @@
-/* This is an implementation of the threads API of POSIX 1003.1-2001.
- *
- * --------------------------------------------------------------------------
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright(C) 1998 John E. Bossom
- * Copyright(C) 1999,2005 Pthreads-win32 contributors
- *
- * Contact Email: rpj@callisto.canberra.edu.au
- *
- * The current list of contributors is contained
- * in the file CONTRIBUTORS included with the source
- * code distribution. The list can also be seen at the
- * following World Wide Web location:
- * http://sources.redhat.com/pthreads-win32/contributors.html
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-
-#if !defined( PTHREAD_H )
-#define PTHREAD_H
-
-/*
- * See the README file for an explanation of the pthreads-win32 version
- * numbering scheme and how the DLL is named etc.
- */
-#define PTW32_VERSION 2,9,1,0
-#define PTW32_VERSION_STRING "2, 9, 1, 0\0"
-
-/* There are three implementations of cancel cleanup.
- * Note that pthread.h is included in both application
- * compilation units and also internally for the library.
- * The code here and within the library aims to work
- * for all reasonable combinations of environments.
- *
- * The three implementations are:
- *
- * WIN32 SEH
- * C
- * C++
- *
- * Please note that exiting a push/pop block via
- * "return", "exit", "break", or "continue" will
- * lead to different behaviour amongst applications
- * depending upon whether the library was built
- * using SEH, C++, or C. For example, a library built
- * with SEH will call the cleanup routine, while both
- * C++ and C built versions will not.
- */
-
-/*
- * Define defaults for cleanup code.
- * Note: Unless the build explicitly defines one of the following, then
- * we default to standard C style cleanup. This style uses setjmp/longjmp
- * in the cancelation and thread exit implementations and therefore won't
- * do stack unwinding if linked to applications that have it (e.g.
- * C++ apps). This is currently consistent with most/all commercial Unix
- * POSIX threads implementations.
- */
-#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C )
-# define __CLEANUP_C
-#endif
-
-#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC))
-#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler.
-#endif
-
-/*
- * Stop here if we are being included by the resource compiler.
- */
-#if !defined(RC_INVOKED)
-
-#undef PTW32_LEVEL
-
-#if defined(_POSIX_SOURCE)
-#define PTW32_LEVEL 0
-/* Early POSIX */
-#endif
-
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
-#undef PTW32_LEVEL
-#define PTW32_LEVEL 1
-/* Include 1b, 1c and 1d */
-#endif
-
-#if defined(INCLUDE_NP)
-#undef PTW32_LEVEL
-#define PTW32_LEVEL 2
-/* Include Non-Portable extensions */
-#endif
-
-#define PTW32_LEVEL_MAX 3
-
-#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL)
-#define PTW32_LEVEL PTW32_LEVEL_MAX
-/* Include everything */
-#endif
-
-#if defined(_UWIN)
-# define HAVE_STRUCT_TIMESPEC 1
-# define HAVE_SIGNAL_H 1
-# undef HAVE_PTW32_CONFIG_H
-# pragma comment(lib, "pthread")
-#endif
-
-/*
- * -------------------------------------------------------------
- *
- *
- * Module: pthread.h
- *
- * Purpose:
- * Provides an implementation of PThreads based upon the
- * standard:
- *
- * POSIX 1003.1-2001
- * and
- * The Single Unix Specification version 3
- *
- * (these two are equivalent)
- *
- * in order to enhance code portability between Windows,
- * various commercial Unix implementations, and Linux.
- *
- * See the ANNOUNCE file for a full list of conforming
- * routines and defined constants, and a list of missing
- * routines and constants not defined in this implementation.
- *
- * Authors:
- * There have been many contributors to this library.
- * The initial implementation was contributed by
- * John Bossom, and several others have provided major
- * sections or revisions of parts of the implementation.
- * Often significant effort has been contributed to
- * find and fix important bugs and other problems to
- * improve the reliability of the library, which sometimes
- * is not reflected in the amount of code which changed as
- * result.
- * As much as possible, the contributors are acknowledged
- * in the ChangeLog file in the source code distribution
- * where their changes are noted in detail.
- *
- * Contributors are listed in the CONTRIBUTORS file.
- *
- * As usual, all bouquets go to the contributors, and all
- * brickbats go to the project maintainer.
- *
- * Maintainer:
- * The code base for this project is coordinated and
- * eventually pre-tested, packaged, and made available by
- *
- * Ross Johnson <rpj@callisto.canberra.edu.au>
- *
- * QA Testers:
- * Ultimately, the library is tested in the real world by
- * a host of competent and demanding scientists and
- * engineers who report bugs and/or provide solutions
- * which are then fixed or incorporated into subsequent
- * versions of the library. Each time a bug is fixed, a
- * test case is written to prove the fix and ensure
- * that later changes to the code don't reintroduce the
- * same error. The number of test cases is slowly growing
- * and therefore so is the code reliability.
- *
- * Compliance:
- * See the file ANNOUNCE for the list of implemented
- * and not-implemented routines and defined options.
- * Of course, these are all defined is this file as well.
- *
- * Web site:
- * The source code and other information about this library
- * are available from
- *
- * http://sources.redhat.com/pthreads-win32/
- *
- * -------------------------------------------------------------
- */
-
-/* Try to avoid including windows.h */
-#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus)
-#define PTW32_INCLUDE_WINDOWS_H
-#endif
-
-#if defined(PTW32_INCLUDE_WINDOWS_H)
-#include <windows.h>
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__)
-/*
- * VC++6.0 or early compiler's header has no DWORD_PTR type.
- */
-typedef unsigned long DWORD_PTR;
-typedef unsigned long ULONG_PTR;
-#endif
-/*
- * -----------------
- * autoconf switches
- * -----------------
- */
-
-#if defined(HAVE_PTW32_CONFIG_H)
-#include "config.h"
-#endif /* HAVE_PTW32_CONFIG_H */
-
-#if !defined(NEED_FTIME)
-#include <time.h>
-#else /* NEED_FTIME */
-/* use native WIN32 time API */
-#endif /* NEED_FTIME */
-
-#if defined(HAVE_SIGNAL_H)
-#include <signal.h>
-#endif /* HAVE_SIGNAL_H */
-
-#include <limits.h>
-
-/*
- * Boolean values to make us independent of system includes.
- */
-enum {
- PTW32_FALSE = 0,
- PTW32_TRUE = (! PTW32_FALSE)
-};
-
-/*
- * This is a duplicate of what is in the autoconf config.h,
- * which is only used when building the pthread-win32 libraries.
- */
-
-#if !defined(PTW32_CONFIG_H)
-# if defined(WINCE)
-# define NEED_ERRNO
-# define NEED_SEM
-# endif
-# if defined(__MINGW64__)
-# define HAVE_STRUCT_TIMESPEC
-# define HAVE_MODE_T
-# elif defined(_UWIN) || defined(__MINGW32__)
-# define HAVE_MODE_T
-# endif
-#endif
-
-/*
- *
- */
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-#if defined(NEED_ERRNO)
-#include "need_errno.h"
-#else
-#include <errno.h>
-#endif
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-/*
- * Several systems don't define some error numbers.
- */
-#if !defined(ENOTSUP)
-# define ENOTSUP 48 /* This is the value in Solaris. */
-#endif
-
-#if !defined(ETIMEDOUT)
-# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */
-#endif
-
-#if !defined(ENOSYS)
-# define ENOSYS 140 /* Semi-arbitrary value */
-#endif
-
-#if !defined(EDEADLK)
-# if defined(EDEADLOCK)
-# define EDEADLK EDEADLOCK
-# else
-# define EDEADLK 36 /* This is the value in MSVC. */
-# endif
-#endif
-
-/* POSIX 2008 - related to robust mutexes */
-#if !defined(EOWNERDEAD)
-# define EOWNERDEAD 43
-#endif
-#if !defined(ENOTRECOVERABLE)
-# define ENOTRECOVERABLE 44
-#endif
-
-#include <sched.h>
-
-/*
- * To avoid including windows.h we define only those things that we
- * actually need from it.
- */
-#if !defined(PTW32_INCLUDE_WINDOWS_H)
-#if !defined(HANDLE)
-# define PTW32__HANDLE_DEF
-# define HANDLE void *
-#endif
-#if !defined(DWORD)
-# define PTW32__DWORD_DEF
-# define DWORD unsigned long
-#endif
-#endif
-
-#if !defined(HAVE_STRUCT_TIMESPEC)
-#define HAVE_STRUCT_TIMESPEC
-#if !defined(_TIMESPEC_DEFINED)
-#define _TIMESPEC_DEFINED
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-#endif /* _TIMESPEC_DEFINED */
-#endif /* HAVE_STRUCT_TIMESPEC */
-
-#if !defined(SIG_BLOCK)
-#define SIG_BLOCK 0
-#endif /* SIG_BLOCK */
-
-#if !defined(SIG_UNBLOCK)
-#define SIG_UNBLOCK 1
-#endif /* SIG_UNBLOCK */
-
-#if !defined(SIG_SETMASK)
-#define SIG_SETMASK 2
-#endif /* SIG_SETMASK */
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * -------------------------------------------------------------
- *
- * POSIX 1003.1-2001 Options
- * =========================
- *
- * Options are normally set in <unistd.h>, which is not provided
- * with pthreads-win32.
- *
- * For conformance with the Single Unix Specification (version 3), all of the
- * options below are defined, and have a value of either -1 (not supported)
- * or 200112L (supported).
- *
- * These options can neither be left undefined nor have a value of 0, because
- * either indicates that sysconf(), which is not implemented, may be used at
- * runtime to check the status of the option.
- *
- * _POSIX_THREADS (== 200112L)
- * If == 200112L, you can use threads
- *
- * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
- * If == 200112L, you can control the size of a thread's
- * stack
- * pthread_attr_getstacksize
- * pthread_attr_setstacksize
- *
- * _POSIX_THREAD_ATTR_STACKADDR (== -1)
- * If == 200112L, you can allocate and control a thread's
- * stack. If not supported, the following functions
- * will return ENOSYS, indicating they are not
- * supported:
- * pthread_attr_getstackaddr
- * pthread_attr_setstackaddr
- *
- * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
- * If == 200112L, you can use realtime scheduling.
- * This option indicates that the behaviour of some
- * implemented functions conforms to the additional TPS
- * requirements in the standard. E.g. rwlocks favour
- * writers over readers when threads have equal priority.
- *
- * _POSIX_THREAD_PRIO_INHERIT (== -1)
- * If == 200112L, you can create priority inheritance
- * mutexes.
- * pthread_mutexattr_getprotocol +
- * pthread_mutexattr_setprotocol +
- *
- * _POSIX_THREAD_PRIO_PROTECT (== -1)
- * If == 200112L, you can create priority ceiling mutexes
- * Indicates the availability of:
- * pthread_mutex_getprioceiling
- * pthread_mutex_setprioceiling
- * pthread_mutexattr_getprioceiling
- * pthread_mutexattr_getprotocol +
- * pthread_mutexattr_setprioceiling
- * pthread_mutexattr_setprotocol +
- *
- * _POSIX_THREAD_PROCESS_SHARED (== -1)
- * If set, you can create mutexes and condition
- * variables that can be shared with another
- * process.If set, indicates the availability
- * of:
- * pthread_mutexattr_getpshared
- * pthread_mutexattr_setpshared
- * pthread_condattr_getpshared
- * pthread_condattr_setpshared
- *
- * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
- * If == 200112L you can use the special *_r library
- * functions that provide thread-safe behaviour
- *
- * _POSIX_READER_WRITER_LOCKS (== 200112L)
- * If == 200112L, you can use read/write locks
- *
- * _POSIX_SPIN_LOCKS (== 200112L)
- * If == 200112L, you can use spin locks
- *
- * _POSIX_BARRIERS (== 200112L)
- * If == 200112L, you can use barriers
- *
- * + These functions provide both 'inherit' and/or
- * 'protect' protocol, based upon these macro
- * settings.
- *
- * -------------------------------------------------------------
- */
-
-/*
- * POSIX Options
- */
-#undef _POSIX_THREADS
-#define _POSIX_THREADS 200809L
-
-#undef _POSIX_READER_WRITER_LOCKS
-#define _POSIX_READER_WRITER_LOCKS 200809L
-
-#undef _POSIX_SPIN_LOCKS
-#define _POSIX_SPIN_LOCKS 200809L
-
-#undef _POSIX_BARRIERS
-#define _POSIX_BARRIERS 200809L
-
-#undef _POSIX_THREAD_SAFE_FUNCTIONS
-#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L
-
-#undef _POSIX_THREAD_ATTR_STACKSIZE
-#define _POSIX_THREAD_ATTR_STACKSIZE 200809L
-
-/*
- * The following options are not supported
- */
-#undef _POSIX_THREAD_ATTR_STACKADDR
-#define _POSIX_THREAD_ATTR_STACKADDR -1
-
-#undef _POSIX_THREAD_PRIO_INHERIT
-#define _POSIX_THREAD_PRIO_INHERIT -1
-
-#undef _POSIX_THREAD_PRIO_PROTECT
-#define _POSIX_THREAD_PRIO_PROTECT -1
-
-/* TPS is not fully supported. */
-#undef _POSIX_THREAD_PRIORITY_SCHEDULING
-#define _POSIX_THREAD_PRIORITY_SCHEDULING -1
-
-#undef _POSIX_THREAD_PROCESS_SHARED
-#define _POSIX_THREAD_PROCESS_SHARED -1
-
-
-/*
- * POSIX 1003.1-2001 Limits
- * ===========================
- *
- * These limits are normally set in <limits.h>, which is not provided with
- * pthreads-win32.
- *
- * PTHREAD_DESTRUCTOR_ITERATIONS
- * Maximum number of attempts to destroy
- * a thread's thread-specific data on
- * termination (must be at least 4)
- *
- * PTHREAD_KEYS_MAX
- * Maximum number of thread-specific data keys
- * available per process (must be at least 128)
- *
- * PTHREAD_STACK_MIN
- * Minimum supported stack size for a thread
- *
- * PTHREAD_THREADS_MAX
- * Maximum number of threads supported per
- * process (must be at least 64).
- *
- * SEM_NSEMS_MAX
- * The maximum number of semaphores a process can have.
- * (must be at least 256)
- *
- * SEM_VALUE_MAX
- * The maximum value a semaphore can have.
- * (must be at least 32767)
- *
- */
-#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4
-
-#undef PTHREAD_DESTRUCTOR_ITERATIONS
-#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
-
-#undef _POSIX_THREAD_KEYS_MAX
-#define _POSIX_THREAD_KEYS_MAX 128
-
-#undef PTHREAD_KEYS_MAX
-#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX
-
-#undef PTHREAD_STACK_MIN
-#define PTHREAD_STACK_MIN 0
-
-#undef _POSIX_THREAD_THREADS_MAX
-#define _POSIX_THREAD_THREADS_MAX 64
-
- /* Arbitrary value */
-#undef PTHREAD_THREADS_MAX
-#define PTHREAD_THREADS_MAX 2019
-
-#undef _POSIX_SEM_NSEMS_MAX
-#define _POSIX_SEM_NSEMS_MAX 256
-
- /* Arbitrary value */
-#undef SEM_NSEMS_MAX
-#define SEM_NSEMS_MAX 1024
-
-#undef _POSIX_SEM_VALUE_MAX
-#define _POSIX_SEM_VALUE_MAX 32767
-
-#undef SEM_VALUE_MAX
-#define SEM_VALUE_MAX INT_MAX
-
-
-#if defined(__GNUC__) && !defined(__declspec)
-# error Please upgrade your GNU compiler to one that supports __declspec.
-#endif
-
-/*
- * When building the library, you should define PTW32_BUILD so that
- * the variables/functions are exported correctly. When using the library,
- * do NOT define PTW32_BUILD, and then the variables/functions will
- * be imported correctly.
- */
-#if !defined(PTW32_STATIC_LIB)
-# if defined(PTW32_BUILD)
-# define PTW32_DLLPORT __declspec (dllexport)
-# else
-# define PTW32_DLLPORT __declspec (dllimport)
-# endif
-#else
-# define PTW32_DLLPORT
-#endif
-
-/*
- * The Open Watcom C/C++ compiler uses a non-standard calling convention
- * that passes function args in registers unless __cdecl is explicitly specified
- * in exposed function prototypes.
- *
- * We force all calls to cdecl even though this could slow Watcom code down
- * slightly. If you know that the Watcom compiler will be used to build both
- * the DLL and application, then you can probably define this as a null string.
- * Remember that pthread.h (this file) is used for both the DLL and application builds.
- */
-#define PTW32_CDECL __cdecl
-
-#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX
-# include <sys/types.h>
-#else
-/*
- * Generic handle type - intended to extend uniqueness beyond
- * that available with a simple pointer. It should scale for either
- * IA-32 or IA-64.
- */
-typedef struct {
- void * p; /* Pointer to actual object */
- unsigned int x; /* Extra information - reuse count etc */
-} ptw32_handle_t;
-
-typedef ptw32_handle_t pthread_t;
-typedef struct pthread_attr_t_ * pthread_attr_t;
-typedef struct pthread_once_t_ pthread_once_t;
-typedef struct pthread_key_t_ * pthread_key_t;
-typedef struct pthread_mutex_t_ * pthread_mutex_t;
-typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
-typedef struct pthread_cond_t_ * pthread_cond_t;
-typedef struct pthread_condattr_t_ * pthread_condattr_t;
-#endif
-typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
-typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
-typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
-typedef struct pthread_barrier_t_ * pthread_barrier_t;
-typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
-
-/*
- * ====================
- * ====================
- * POSIX Threads
- * ====================
- * ====================
- */
-
-enum {
-/*
- * pthread_attr_{get,set}detachstate
- */
- PTHREAD_CREATE_JOINABLE = 0, /* Default */
- PTHREAD_CREATE_DETACHED = 1,
-
-/*
- * pthread_attr_{get,set}inheritsched
- */
- PTHREAD_INHERIT_SCHED = 0,
- PTHREAD_EXPLICIT_SCHED = 1, /* Default */
-
-/*
- * pthread_{get,set}scope
- */
- PTHREAD_SCOPE_PROCESS = 0,
- PTHREAD_SCOPE_SYSTEM = 1, /* Default */
-
-/*
- * pthread_setcancelstate paramters
- */
- PTHREAD_CANCEL_ENABLE = 0, /* Default */
- PTHREAD_CANCEL_DISABLE = 1,
-
-/*
- * pthread_setcanceltype parameters
- */
- PTHREAD_CANCEL_ASYNCHRONOUS = 0,
- PTHREAD_CANCEL_DEFERRED = 1, /* Default */
-
-/*
- * pthread_mutexattr_{get,set}pshared
- * pthread_condattr_{get,set}pshared
- */
- PTHREAD_PROCESS_PRIVATE = 0,
- PTHREAD_PROCESS_SHARED = 1,
-
-/*
- * pthread_mutexattr_{get,set}robust
- */
- PTHREAD_MUTEX_STALLED = 0, /* Default */
- PTHREAD_MUTEX_ROBUST = 1,
-
-/*
- * pthread_barrier_wait
- */
- PTHREAD_BARRIER_SERIAL_THREAD = -1
-};
-
-/*
- * ====================
- * ====================
- * Cancelation
- * ====================
- * ====================
- */
-#define PTHREAD_CANCELED ((void *)(size_t) -1)
-
-
-/*
- * ====================
- * ====================
- * Once Key
- * ====================
- * ====================
- */
-#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0}
-
-struct pthread_once_t_
-{
- int done; /* indicates if user function has been executed */
- void * lock;
- int reserved1;
- int reserved2;
-};
-
-
-/*
- * ====================
- * ====================
- * Object initialisers
- * ====================
- * ====================
- */
-#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1)
-#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2)
-#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3)
-
-/*
- * Compatibility with LinuxThreads
- */
-#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
-
-#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1)
-
-#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1)
-
-#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1)
-
-
-/*
- * Mutex types.
- */
-enum
-{
- /* Compatibility with LinuxThreads */
- PTHREAD_MUTEX_FAST_NP,
- PTHREAD_MUTEX_RECURSIVE_NP,
- PTHREAD_MUTEX_ERRORCHECK_NP,
- PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
- PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
- /* For compatibility with POSIX */
- PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
- PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
- PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
- PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
-};
-
-
-typedef struct ptw32_cleanup_t ptw32_cleanup_t;
-
-#if defined(_MSC_VER)
-/* Disable MSVC 'anachronism used' warning */
-#pragma warning( disable : 4229 )
-#endif
-
-typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *);
-
-#if defined(_MSC_VER)
-#pragma warning( default : 4229 )
-#endif
-
-struct ptw32_cleanup_t
-{
- ptw32_cleanup_callback_t routine;
- void *arg;
- struct ptw32_cleanup_t *prev;
-};
-
-#if defined(__CLEANUP_SEH)
- /*
- * WIN32 SEH version of cancel cleanup.
- */
-
-#define pthread_cleanup_push( _rout, _arg ) \
- { \
- ptw32_cleanup_t _cleanup; \
- \
- _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \
- _cleanup.arg = (_arg); \
- __try \
- { \
-
-#define pthread_cleanup_pop( _execute ) \
- } \
- __finally \
- { \
- if( _execute || AbnormalTermination()) \
- { \
- (*(_cleanup.routine))( _cleanup.arg ); \
- } \
- } \
- }
-
-#else /* __CLEANUP_SEH */
-
-#if defined(__CLEANUP_C)
-
- /*
- * C implementation of PThreads cancel cleanup
- */
-
-#define pthread_cleanup_push( _rout, _arg ) \
- { \
- ptw32_cleanup_t _cleanup; \
- \
- ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \
-
-#define pthread_cleanup_pop( _execute ) \
- (void) ptw32_pop_cleanup( _execute ); \
- }
-
-#else /* __CLEANUP_C */
-
-#if defined(__CLEANUP_CXX)
-
- /*
- * C++ version of cancel cleanup.
- * - John E. Bossom.
- */
-
- class PThreadCleanup {
- /*
- * PThreadCleanup
- *
- * Purpose
- * This class is a C++ helper class that is
- * used to implement pthread_cleanup_push/
- * pthread_cleanup_pop.
- * The destructor of this class automatically
- * pops the pushed cleanup routine regardless
- * of how the code exits the scope
- * (i.e. such as by an exception)
- */
- ptw32_cleanup_callback_t cleanUpRout;
- void * obj;
- int executeIt;
-
- public:
- PThreadCleanup() :
- cleanUpRout( 0 ),
- obj( 0 ),
- executeIt( 0 )
- /*
- * No cleanup performed
- */
- {
- }
-
- PThreadCleanup(
- ptw32_cleanup_callback_t routine,
- void * arg ) :
- cleanUpRout( routine ),
- obj( arg ),
- executeIt( 1 )
- /*
- * Registers a cleanup routine for 'arg'
- */
- {
- }
-
- ~PThreadCleanup()
- {
- if ( executeIt && ((void *) cleanUpRout != (void *) 0) )
- {
- (void) (*cleanUpRout)( obj );
- }
- }
-
- void execute( int exec )
- {
- executeIt = exec;
- }
- };
-
- /*
- * C++ implementation of PThreads cancel cleanup;
- * This implementation takes advantage of a helper
- * class who's destructor automatically calls the
- * cleanup routine if we exit our scope weirdly
- */
-#define pthread_cleanup_push( _rout, _arg ) \
- { \
- PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \
- (void *) (_arg) );
-
-#define pthread_cleanup_pop( _execute ) \
- cleanup.execute( _execute ); \
- }
-
-#else
-
-#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
-
-#endif /* __CLEANUP_CXX */
-
-#endif /* __CLEANUP_C */
-
-#endif /* __CLEANUP_SEH */
-
-/*
- * ===============
- * ===============
- * Methods
- * ===============
- * ===============
- */
-
-/*
- * PThread Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr,
- int *detachstate);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr,
- void **stackaddr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr,
- size_t * stacksize);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr,
- int detachstate);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr,
- void *stackaddr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr,
- size_t stacksize);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr,
- struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr,
- const struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *,
- int);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *,
- int *);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr,
- int inheritsched);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr,
- int * inheritsched);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *,
- int);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *,
- int *);
-
-/*
- * PThread Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid,
- const pthread_attr_t * attr,
- void *(PTW32_CDECL *start) (void *),
- void *arg);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1,
- pthread_t t2);
-
-PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread,
- void **value_ptr);
-
-PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state,
- int *oldstate);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type,
- int *oldtype);
-
-PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control,
- void (PTW32_CDECL *init_routine) (void));
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute);
-
-PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup,
- ptw32_cleanup_callback_t routine,
- void *arg);
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-/*
- * Thread Specific Data Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key,
- void (PTW32_CDECL *destructor) (void *));
-
-PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key,
- const void *value);
-
-PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key);
-
-
-/*
- * Mutex Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t
- * attr,
- int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
- int pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust(
- pthread_mutexattr_t *attr,
- int robust);
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust(
- const pthread_mutexattr_t * attr,
- int * robust);
-
-/*
- * Barrier Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t
- * attr,
- int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
- int pshared);
-
-/*
- * Mutex Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex,
- const pthread_mutexattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex,
- const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex);
-
-/*
- * Spinlock Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock);
-
-/*
- * Barrier Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier,
- const pthread_barrierattr_t * attr,
- unsigned int count);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier);
-
-/*
- * Condition Variable Attribute Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr,
- int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr,
- int pshared);
-
-/*
- * Condition Variable Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,
- const pthread_condattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond,
- pthread_mutex_t * mutex);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,
- pthread_mutex_t * mutex,
- const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);
-
-/*
- * Scheduling
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread,
- int policy,
- const struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread,
- int *policy,
- struct sched_param *param);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void);
-
-/*
- * Read-Write Lock Functions
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock,
- const pthread_rwlockattr_t *attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
- const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
- const struct timespec *abstime);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
- int *pshared);
-
-PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
- int pshared);
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1
-
-/*
- * Signal Functions. Should be defined in <signal.h> but MSVC and MinGW32
- * already have signal.h that don't define these.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig);
-
-/*
- * Non-portable functions
- */
-
-/*
- * Compatibility with Linux.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
- int kind);
-PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
- int *kind);
-
-/*
- * Possibly supported by other POSIX threads implementations
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval);
-PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void);
-PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread);
-
-/*
- * Useful if an application wants to statically link
- * the lib rather than load the DLL at run-time.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void);
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void);
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void);
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void);
-
-/*
- * Features that are auto-detected at load/run time.
- */
-PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int);
-enum ptw32_features {
- PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */
- PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */
-};
-
-/*
- * Register a system time change with the library.
- * Causes the library to perform various functions
- * in response to the change. Should be called whenever
- * the application's top level window receives a
- * WM_TIMECHANGE message. It can be passed directly to
- * pthread_create() as a new thread if desired.
- */
-PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *);
-
-#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-
-/*
- * Returns the Win32 HANDLE for the POSIX thread.
- */
-PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread);
-/*
- * Returns the win32 thread ID for POSIX thread.
- */
-PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread);
-
-
-/*
- * Protected Methods
- *
- * This function blocks until the given WIN32 handle
- * is signaled or pthread_cancel had been called.
- * This function allows the caller to hook into the
- * PThreads cancel mechanism. It is implemented using
- *
- * WaitForMultipleObjects
- *
- * on 'waitHandle' and a manually reset WIN32 Event
- * used to implement pthread_cancel. The 'timeout'
- * argument to TimedWait is simply passed to
- * WaitForMultipleObjects.
- */
-PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle);
-PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle,
- DWORD timeout);
-
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-/*
- * Thread-Safe C Runtime Library Mappings.
- */
-#if !defined(_UWIN)
-# if defined(NEED_ERRNO)
- PTW32_DLLPORT int * PTW32_CDECL _errno( void );
-# else
-# if !defined(errno)
-# if (defined(_MT) || defined(_DLL))
- __declspec(dllimport) extern int * __cdecl _errno(void);
-# define errno (*_errno())
-# endif
-# endif
-# endif
-#endif
-
-/*
- * Some compiler environments don't define some things.
- */
-#if defined(__BORLANDC__)
-# define _ftime ftime
-# define _timeb timeb
-#endif
-
-#if defined(__cplusplus)
-
-/*
- * Internal exceptions
- */
-class ptw32_exception {};
-class ptw32_exception_cancel : public ptw32_exception {};
-class ptw32_exception_exit : public ptw32_exception {};
-
-#endif
-
-#if PTW32_LEVEL >= PTW32_LEVEL_MAX
-
-/* FIXME: This is only required if the library was built using SEH */
-/*
- * Get internal SEH tag
- */
-PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void);
-
-#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */
-
-#if !defined(PTW32_BUILD)
-
-#if defined(__CLEANUP_SEH)
-
-/*
- * Redefine the SEH __except keyword to ensure that applications
- * propagate our internal exceptions up to the library's internal handlers.
- */
-#define __except( E ) \
- __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \
- ? EXCEPTION_CONTINUE_SEARCH : ( E ) )
-
-#endif /* __CLEANUP_SEH */
-
-#if defined(__CLEANUP_CXX)
-
-/*
- * Redefine the C++ catch keyword to ensure that applications
- * propagate our internal exceptions up to the library's internal handlers.
- */
-#if defined(_MSC_VER)
- /*
- * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll'
- * if you want Pthread-Win32 cancelation and pthread_exit to work.
- */
-
-#if !defined(PtW32NoCatchWarn)
-
-#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.")
-#pragma message("------------------------------------------------------------------")
-#pragma message("When compiling applications with MSVC++ and C++ exception handling:")
-#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads")
-#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread")
-#pragma message(" cancelation and pthread_exit to work. For example:")
-#pragma message("")
-#pragma message(" #if defined(PtW32CatchAll)")
-#pragma message(" PtW32CatchAll")
-#pragma message(" #else")
-#pragma message(" catch(...)")
-#pragma message(" #endif")
-#pragma message(" {")
-#pragma message(" /* Catchall block processing */")
-#pragma message(" }")
-#pragma message("------------------------------------------------------------------")
-
-#endif
-
-#define PtW32CatchAll \
- catch( ptw32_exception & ) { throw; } \
- catch( ... )
-
-#else /* _MSC_VER */
-
-#define catch( E ) \
- catch( ptw32_exception & ) { throw; } \
- catch( E )
-
-#endif /* _MSC_VER */
-
-#endif /* __CLEANUP_CXX */
-
-#endif /* ! PTW32_BUILD */
-
-#if defined(__cplusplus)
-} /* End of extern "C" */
-#endif /* __cplusplus */
-
-#if defined(PTW32__HANDLE_DEF)
-# undef HANDLE
-#endif
-#if defined(PTW32__DWORD_DEF)
-# undef DWORD
-#endif
-
-#undef PTW32_LEVEL
-#undef PTW32_LEVEL_MAX
-
-#endif /* ! RC_INVOKED */
-
-#endif /* PTHREAD_H */
diff --git a/src/external/pthread/include/sched.h b/src/external/pthread/include/sched.h
deleted file mode 100644
index f36a97a6..00000000
--- a/src/external/pthread/include/sched.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Module: sched.h
- *
- * Purpose:
- * Provides an implementation of POSIX realtime extensions
- * as defined in
- *
- * POSIX 1003.1b-1993 (POSIX.1b)
- *
- * --------------------------------------------------------------------------
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright(C) 1998 John E. Bossom
- * Copyright(C) 1999,2005 Pthreads-win32 contributors
- *
- * Contact Email: rpj@callisto.canberra.edu.au
- *
- * The current list of contributors is contained
- * in the file CONTRIBUTORS included with the source
- * code distribution. The list can also be seen at the
- * following World Wide Web location:
- * http://sources.redhat.com/pthreads-win32/contributors.html
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#if !defined(_SCHED_H)
-#define _SCHED_H
-
-#undef PTW32_SCHED_LEVEL
-
-#if defined(_POSIX_SOURCE)
-#define PTW32_SCHED_LEVEL 0
-/* Early POSIX */
-#endif
-
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
-#undef PTW32_SCHED_LEVEL
-#define PTW32_SCHED_LEVEL 1
-/* Include 1b, 1c and 1d */
-#endif
-
-#if defined(INCLUDE_NP)
-#undef PTW32_SCHED_LEVEL
-#define PTW32_SCHED_LEVEL 2
-/* Include Non-Portable extensions */
-#endif
-
-#define PTW32_SCHED_LEVEL_MAX 3
-
-#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL)
-#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX
-/* Include everything */
-#endif
-
-
-#if defined(__GNUC__) && !defined(__declspec)
-# error Please upgrade your GNU compiler to one that supports __declspec.
-#endif
-
-/*
- * When building the library, you should define PTW32_BUILD so that
- * the variables/functions are exported correctly. When using the library,
- * do NOT define PTW32_BUILD, and then the variables/functions will
- * be imported correctly.
- */
-#if !defined(PTW32_STATIC_LIB)
-# if defined(PTW32_BUILD)
-# define PTW32_DLLPORT __declspec (dllexport)
-# else
-# define PTW32_DLLPORT __declspec (dllimport)
-# endif
-#else
-# define PTW32_DLLPORT
-#endif
-
-/*
- * This is a duplicate of what is in the autoconf config.h,
- * which is only used when building the pthread-win32 libraries.
- */
-
-#if !defined(PTW32_CONFIG_H)
-# if defined(WINCE)
-# define NEED_ERRNO
-# define NEED_SEM
-# endif
-# if defined(__MINGW64__)
-# define HAVE_STRUCT_TIMESPEC
-# define HAVE_MODE_T
-# elif defined(_UWIN) || defined(__MINGW32__)
-# define HAVE_MODE_T
-# endif
-#endif
-
-/*
- *
- */
-
-#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
-#if defined(NEED_ERRNO)
-#include "need_errno.h"
-#else
-#include <errno.h>
-#endif
-#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */
-
-#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN)
-# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX
-/* For pid_t */
-# include <sys/types.h>
-/* Required by Unix 98 */
-# include <time.h>
-# else
- typedef int pid_t;
-# endif
-#else
- typedef int pid_t;
-#endif
-
-/* Thread scheduling policies */
-
-enum {
- SCHED_OTHER = 0,
- SCHED_FIFO,
- SCHED_RR,
- SCHED_MIN = SCHED_OTHER,
- SCHED_MAX = SCHED_RR
-};
-
-struct sched_param {
- int sched_priority;
-};
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif /* __cplusplus */
-
-PTW32_DLLPORT int __cdecl sched_yield (void);
-
-PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy);
-
-PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy);
-
-PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy);
-
-PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid);
-
-/*
- * Note that this macro returns ENOTSUP rather than
- * ENOSYS as might be expected. However, returning ENOSYS
- * should mean that sched_get_priority_{min,max} are
- * not implemented as well as sched_rr_get_interval.
- * This is not the case, since we just don't support
- * round-robin scheduling. Therefore I have chosen to
- * return the same value as sched_setscheduler when
- * SCHED_RR is passed to it.
- */
-#define sched_rr_get_interval(_pid, _interval) \
- ( errno = ENOTSUP, (int) -1 )
-
-
-#if defined(__cplusplus)
-} /* End of extern "C" */
-#endif /* __cplusplus */
-
-#undef PTW32_SCHED_LEVEL
-#undef PTW32_SCHED_LEVEL_MAX
-
-#endif /* !_SCHED_H */
-
diff --git a/src/external/pthread/include/semaphore.h b/src/external/pthread/include/semaphore.h
deleted file mode 100644
index c6e9407e..00000000
--- a/src/external/pthread/include/semaphore.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Module: semaphore.h
- *
- * Purpose:
- * Semaphores aren't actually part of the PThreads standard.
- * They are defined by the POSIX Standard:
- *
- * POSIX 1003.1b-1993 (POSIX.1b)
- *
- * --------------------------------------------------------------------------
- *
- * Pthreads-win32 - POSIX Threads Library for Win32
- * Copyright(C) 1998 John E. Bossom
- * Copyright(C) 1999,2005 Pthreads-win32 contributors
- *
- * Contact Email: rpj@callisto.canberra.edu.au
- *
- * The current list of contributors is contained
- * in the file CONTRIBUTORS included with the source
- * code distribution. The list can also be seen at the
- * following World Wide Web location:
- * http://sources.redhat.com/pthreads-win32/contributors.html
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library in the file COPYING.LIB;
- * if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#if !defined( SEMAPHORE_H )
-#define SEMAPHORE_H
-
-#undef PTW32_SEMAPHORE_LEVEL
-
-#if defined(_POSIX_SOURCE)
-#define PTW32_SEMAPHORE_LEVEL 0
-/* Early POSIX */
-#endif
-
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
-#undef PTW32_SEMAPHORE_LEVEL
-#define PTW32_SEMAPHORE_LEVEL 1
-/* Include 1b, 1c and 1d */
-#endif
-
-#if defined(INCLUDE_NP)
-#undef PTW32_SEMAPHORE_LEVEL
-#define PTW32_SEMAPHORE_LEVEL 2
-/* Include Non-Portable extensions */
-#endif
-
-#define PTW32_SEMAPHORE_LEVEL_MAX 3
-
-#if !defined(PTW32_SEMAPHORE_LEVEL)
-#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX
-/* Include everything */
-#endif
-
-#if defined(__GNUC__) && ! defined (__declspec)
-# error Please upgrade your GNU compiler to one that supports __declspec.
-#endif
-
-/*
- * When building the library, you should define PTW32_BUILD so that
- * the variables/functions are exported correctly. When using the library,
- * do NOT define PTW32_BUILD, and then the variables/functions will
- * be imported correctly.
- */
-#if !defined(PTW32_STATIC_LIB)
-# if defined(PTW32_BUILD)
-# define PTW32_DLLPORT __declspec (dllexport)
-# else
-# define PTW32_DLLPORT __declspec (dllimport)
-# endif
-#else
-# define PTW32_DLLPORT
-#endif
-
-/*
- * This is a duplicate of what is in the autoconf config.h,
- * which is only used when building the pthread-win32 libraries.
- */
-
-#if !defined(PTW32_CONFIG_H)
-# if defined(WINCE)
-# define NEED_ERRNO
-# define NEED_SEM
-# endif
-# if defined(__MINGW64__)
-# define HAVE_STRUCT_TIMESPEC
-# define HAVE_MODE_T
-# elif defined(_UWIN) || defined(__MINGW32__)
-# define HAVE_MODE_T
-# endif
-#endif
-
-/*
- *
- */
-
-#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX
-#if defined(NEED_ERRNO)
-#include "need_errno.h"
-#else
-#include <errno.h>
-#endif
-#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */
-
-#define _POSIX_SEMAPHORES
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif /* __cplusplus */
-
-#if !defined(HAVE_MODE_T)
-typedef unsigned int mode_t;
-#endif
-
-
-typedef struct sem_t_ * sem_t;
-
-PTW32_DLLPORT int __cdecl sem_init (sem_t * sem,
- int pshared,
- unsigned int value);
-
-PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem,
- const struct timespec * abstime);
-
-PTW32_DLLPORT int __cdecl sem_post (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem,
- int count);
-
-PTW32_DLLPORT int __cdecl sem_open (const char * name,
- int oflag,
- mode_t mode,
- unsigned int value);
-
-PTW32_DLLPORT int __cdecl sem_close (sem_t * sem);
-
-PTW32_DLLPORT int __cdecl sem_unlink (const char * name);
-
-PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem,
- int * sval);
-
-#if defined(__cplusplus)
-} /* End of extern "C" */
-#endif /* __cplusplus */
-
-#undef PTW32_SEMAPHORE_LEVEL
-#undef PTW32_SEMAPHORE_LEVEL_MAX
-
-#endif /* !SEMAPHORE_H */
diff --git a/src/external/pthread/lib/libpthreadGC2.a b/src/external/pthread/lib/libpthreadGC2.a
deleted file mode 100644
index df211759..00000000
--- a/src/external/pthread/lib/libpthreadGC2.a
+++ /dev/null
Binary files differ
diff --git a/src/external/pthread/lib/pthreadGC2.dll b/src/external/pthread/lib/pthreadGC2.dll
deleted file mode 100644
index 67b9289d..00000000
--- a/src/external/pthread/lib/pthreadGC2.dll
+++ /dev/null
Binary files differ
diff --git a/src/external/stb_image.h b/src/external/stb_image.h
index 4d8d0133..ae2ada6a 100644
--- a/src/external/stb_image.h
+++ b/src/external/stb_image.h
@@ -1,4 +1,4 @@
-/* stb_image - v2.14 - public domain image loader - http://nothings.org/stb_image.h
+/* stb_image - v2.15 - public domain image loader - http://nothings.org/stb_image.h
no warranty implied; use at your own risk
Do this:
@@ -21,7 +21,7 @@
avoid problematic images and only need the trivial interface
JPEG baseline & progressive (12 bpc/arithmetic not supported, same as stock IJG lib)
- PNG 1/2/4/8-bit-per-channel (16 bpc not supported)
+ PNG 1/2/4/8/16-bit-per-channel
TGA (not sure what subset, if a subset)
BMP non-1bpp, non-RLE
@@ -42,115 +42,19 @@
Full documentation under "DOCUMENTATION" below.
- Revision 2.00 release notes:
-
- - Progressive JPEG is now supported.
-
- - PPM and PGM binary formats are now supported, thanks to Ken Miller.
-
- - x86 platforms now make use of SSE2 SIMD instructions for
- JPEG decoding, and ARM platforms can use NEON SIMD if requested.
- This work was done by Fabian "ryg" Giesen. SSE2 is used by
- default, but NEON must be enabled explicitly; see docs.
-
- With other JPEG optimizations included in this version, we see
- 2x speedup on a JPEG on an x86 machine, and a 1.5x speedup
- on a JPEG on an ARM machine, relative to previous versions of this
- library. The same results will not obtain for all JPGs and for all
- x86/ARM machines. (Note that progressive JPEGs are significantly
- slower to decode than regular JPEGs.) This doesn't mean that this
- is the fastest JPEG decoder in the land; rather, it brings it
- closer to parity with standard libraries. If you want the fastest
- decode, look elsewhere. (See "Philosophy" section of docs below.)
-
- See final bullet items below for more info on SIMD.
-
- - Added STBI_MALLOC, STBI_REALLOC, and STBI_FREE macros for replacing
- the memory allocator. Unlike other STBI libraries, these macros don't
- support a context parameter, so if you need to pass a context in to
- the allocator, you'll have to store it in a global or a thread-local
- variable.
-
- - Split existing STBI_NO_HDR flag into two flags, STBI_NO_HDR and
- STBI_NO_LINEAR.
- STBI_NO_HDR: suppress implementation of .hdr reader format
- STBI_NO_LINEAR: suppress high-dynamic-range light-linear float API
-
- - You can suppress implementation of any of the decoders to reduce
- your code footprint by #defining one or more of the following
- symbols before creating the implementation.
-
- STBI_NO_JPEG
- STBI_NO_PNG
- STBI_NO_BMP
- STBI_NO_PSD
- STBI_NO_TGA
- STBI_NO_GIF
- STBI_NO_HDR
- STBI_NO_PIC
- STBI_NO_PNM (.ppm and .pgm)
-
- - You can request *only* certain decoders and suppress all other ones
- (this will be more forward-compatible, as addition of new decoders
- doesn't require you to disable them explicitly):
-
- STBI_ONLY_JPEG
- STBI_ONLY_PNG
- STBI_ONLY_BMP
- STBI_ONLY_PSD
- STBI_ONLY_TGA
- STBI_ONLY_GIF
- STBI_ONLY_HDR
- STBI_ONLY_PIC
- STBI_ONLY_PNM (.ppm and .pgm)
-
- Note that you can define multiples of these, and you will get all
- of them ("only x" and "only y" is interpreted to mean "only x&y").
-
- - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
- want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
-
- - Compilation of all SIMD code can be suppressed with
- #define STBI_NO_SIMD
- It should not be necessary to disable SIMD unless you have issues
- compiling (e.g. using an x86 compiler which doesn't support SSE
- intrinsics or that doesn't support the method used to detect
- SSE2 support at run-time), and even those can be reported as
- bugs so I can refine the built-in compile-time checking to be
- smarter.
-
- - The old STBI_SIMD system which allowed installing a user-defined
- IDCT etc. has been removed. If you need this, don't upgrade. My
- assumption is that almost nobody was doing this, and those who
- were will find the built-in SIMD more satisfactory anyway.
-
- - RGB values computed for JPEG images are slightly different from
- previous versions of stb_image. (This is due to using less
- integer precision in SIMD.) The C code has been adjusted so
- that the same RGB values will be computed regardless of whether
- SIMD support is available, so your app should always produce
- consistent results. But these results are slightly different from
- previous versions. (Specifically, about 3% of available YCbCr values
- will compute different RGB results from pre-1.49 versions by +-1;
- most of the deviating values are one smaller in the G channel.)
-
- - If you must produce consistent results with previous versions of
- stb_image, #define STBI_JPEG_OLD and you will get the same results
- you used to; however, you will not get the SIMD speedups for
- the YCbCr-to-RGB conversion step (although you should still see
- significant JPEG speedup from the other changes).
-
- Please note that STBI_JPEG_OLD is a temporary feature; it will be
- removed in future versions of the library. It is only intended for
- near-term back-compatibility use.
-
-
- Latest revision history:
+LICENSE
+
+ See end of file for license information.
+
+RECENT REVISION HISTORY:
+
+ 2.15 (2017-03-18) fix png-1,2,4; all Imagenet JPGs; no runtime SSE detection on GCC
+ 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
2.13 (2016-12-04) experimental 16-bit API, only for PNG so far; fixes
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
RGB-format JPEG; remove white matting in PSD;
- allocate large structures on the stack;
+ allocate large structures on the stack;
correct channel count for PNG & BMP
2.10 (2016-01-22) avoid warning introduced in 2.09
2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
@@ -174,32 +78,26 @@
Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
github:urraka (animated gif) Junggon Kim (PNM comments)
Daniel Gibson (16-bit TGA)
- socks-the-fox (16-bit TGA)
+ socks-the-fox (16-bit PNG)
+ Jeremy Sawicki (handle all ImageNet JPGs)
Optimizations & bugfixes
Fabian "ryg" Giesen
Arseny Kapoulkine
Bug & warning fixes
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
- Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson
- Dave Moore Roy Eltham Hayaki Saito Phil Jordan
- Won Chun Luke Graham Johan Duparc Nathan Reed
- the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis
- Janez Zemva John Bartholomew Michal Cichon github:svdijk
- Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
- Laurent Gomila Cort Stratton Sergio Gonzalez github:romigrou
- Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan
- Ryamond Barbiero Paul Du Bois Engin Manap github:snagar
- Michaelangel007@github Oriol Ferrer Mesia Dale Weiler github:Zelex
- Philipp Wiesemann Josh Tobin github:rlyeh github:grim210@github
- Blazej Dariusz Roszkowski github:sammyhw
-
-
-LICENSE
-
-This software is dual-licensed to the public domain and under the following
-license: you are granted a perpetual, irrevocable license to copy, modify,
-publish, and distribute this file as you see fit.
+ Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
+ Dave Moore Roy Eltham Hayaki Saito Nathan Reed
+ Won Chun Luke Graham Johan Duparc Nick Verigakis
+ the Horde3D community Thomas Ruf Ronny Chevalier Baldur Karlsson
+ Janez Zemva John Bartholomew Michal Cichon github:rlyeh
+ Jonathan Blow Ken Hamada Tero Hanninen github:romigrou
+ Laurent Gomila Cort Stratton Sergio Gonzalez github:svdijk
+ Aruelien Pocheville Thibault Reuille Cass Everitt github:snagar
+ Ryamond Barbiero Paul Du Bois Engin Manap github:Zelex
+ Michaelangel007@github Philipp Wiesemann Dale Weiler github:grim210
+ Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:sammyhw
+ Blazej Dariusz Roszkowski Gregory Mullen github:phprus
*/
@@ -274,13 +172,13 @@ publish, and distribute this file as you see fit.
// and for best performance I may provide less-easy-to-use APIs that give higher
// performance, in addition to the easy to use ones. Nevertheless, it's important
// to keep in mind that from the standpoint of you, a client of this library,
-// all you care about is #1 and #3, and stb libraries do not emphasize #3 above all.
+// all you care about is #1 and #3, and stb libraries DO NOT emphasize #3 above all.
//
// Some secondary priorities arise directly from the first two, some of which
// make more explicit reasons why performance can't be emphasized.
//
// - Portable ("ease of use")
-// - Small footprint ("easy to maintain")
+// - Small source code footprint ("easy to maintain")
// - No dependencies ("ease of use")
//
// ===========================================================================
@@ -312,13 +210,6 @@ publish, and distribute this file as you see fit.
// (at least this is true for iOS and Android). Therefore, the NEON support is
// toggled by a build flag: define STBI_NEON to get NEON loops.
//
-// The output of the JPEG decoder is slightly different from versions where
-// SIMD support was introduced (that is, for versions before 1.49). The
-// difference is only +-1 in the 8-bit RGB channels, and only on a small
-// fraction of pixels. You can force the pre-1.49 behavior by defining
-// STBI_JPEG_OLD, but this will disable some of the SIMD decoding path
-// and hence cost some performance.
-//
// If for some reason you do not want to use any of SIMD code, or if
// you have issues compiling it, you can disable it entirely by
// defining STBI_NO_SIMD.
@@ -374,20 +265,47 @@ publish, and distribute this file as you see fit.
// says there's premultiplied data (currently only happens in iPhone images,
// and only if iPhone convert-to-rgb processing is on).
//
+// ===========================================================================
+//
+// ADDITIONAL CONFIGURATION
+//
+// - You can suppress implementation of any of the decoders to reduce
+// your code footprint by #defining one or more of the following
+// symbols before creating the implementation.
+//
+// STBI_NO_JPEG
+// STBI_NO_PNG
+// STBI_NO_BMP
+// STBI_NO_PSD
+// STBI_NO_TGA
+// STBI_NO_GIF
+// STBI_NO_HDR
+// STBI_NO_PIC
+// STBI_NO_PNM (.ppm and .pgm)
+//
+// - You can request *only* certain decoders and suppress all other ones
+// (this will be more forward-compatible, as addition of new decoders
+// doesn't require you to disable them explicitly):
+//
+// STBI_ONLY_JPEG
+// STBI_ONLY_PNG
+// STBI_ONLY_BMP
+// STBI_ONLY_PSD
+// STBI_ONLY_TGA
+// STBI_ONLY_GIF
+// STBI_ONLY_HDR
+// STBI_ONLY_PIC
+// STBI_ONLY_PNM (.ppm and .pgm)
+//
+// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
+// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
+//
#ifndef STBI_NO_STDIO
#include <stdio.h>
#endif // STBI_NO_STDIO
-#define STBI_NO_HDR // RaySan: not required by raylib
-//#define STBI_NO_SIMD // RaySan: issues when compiling with GCC 4.7.2
-
-// NOTE: Added to work with raylib on Android
-#if defined(PLATFORM_ANDROID)
- #include "utils.h" // RaySan: Android fopen function map
-#endif
-
#define STBI_VERSION 1
enum
@@ -666,12 +584,14 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#define STBI__X86_TARGET
#endif
-#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
-// NOTE: not clear do we actually need this for the 64-bit path?
+#if defined(__GNUC__) && defined(STBI__X86_TARGET) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
-// (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
-// this is just broken and gcc are jerks for not fixing it properly
-// http://www.virtualdub.org/blog/pivot/entry.php?id=363 )
+// which in turn means it gets to use SSE2 everywhere. This is unfortunate,
+// but previous attempts to provide the SSE2 functions with runtime
+// detection caused numerous issues. The way architecture extensions are
+// exposed in GCC/Clang is, sadly, not really suited for one-file libs.
+// New behavior: if compiled with -msse2, we use SSE2 without any
+// detection; if not, we don't use it at all.
#define STBI_NO_SIMD
#endif
@@ -729,14 +649,10 @@ static int stbi__sse2_available()
static int stbi__sse2_available()
{
-#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 // GCC 4.8 or later
- // GCC 4.8+ has a nice way to do this
- return __builtin_cpu_supports("sse2");
-#else
- // portable way to do this, preferably without using GCC inline ASM?
- // just bail for now.
- return 0;
-#endif
+ // If we're even attempting to compile this on GCC/Clang, that means
+ // -msse2 is on, which means the compiler is allowed to use SSE2
+ // instructions at will, and so are we.
+ return 1;
}
#endif
#endif
@@ -1738,7 +1654,7 @@ typedef struct
stbi__context *s;
stbi__huffman huff_dc[4];
stbi__huffman huff_ac[4];
- stbi_uc dequant[4][64];
+ stbi__uint16 dequant[4][64];
stbi__int16 fast_ac[4][1 << FAST_BITS];
// sizes for components, interleaved MCUs
@@ -1774,6 +1690,8 @@ typedef struct
int succ_high;
int succ_low;
int eob_run;
+ int jfif;
+ int app14_color_transform; // Adobe APP14 tag
int rgb;
int scan_n, order[4];
@@ -1844,7 +1762,7 @@ static void stbi__build_fast_ac(stbi__int16 *fast_ac, stbi__huffman *h)
// magnitude code followed by receive_extend code
int k = ((i << len) & ((1 << FAST_BITS) - 1)) >> (FAST_BITS - magbits);
int m = 1 << (magbits - 1);
- if (k < m) k += (-1 << magbits) + 1;
+ if (k < m) k += (~0U << magbits) + 1;
// if the result is small enough, we can fit it in fast_ac table
if (k >= -128 && k <= 127)
fast_ac[i] = (stbi__int16) ((k << 8) + (run << 4) + (len + magbits));
@@ -1859,6 +1777,7 @@ static void stbi__grow_buffer_unsafe(stbi__jpeg *j)
int b = j->nomore ? 0 : stbi__get8(j->s);
if (b == 0xff) {
int c = stbi__get8(j->s);
+ while (c == 0xff) c = stbi__get8(j->s); // consume fill bytes
if (c != 0) {
j->marker = (unsigned char) c;
j->nomore = 1;
@@ -1983,7 +1902,7 @@ static stbi_uc stbi__jpeg_dezigzag[64+15] =
};
// decode one 64-entry block--
-static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi_uc *dequant)
+static int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64], stbi__huffman *hdc, stbi__huffman *hac, stbi__int16 *fac, int b, stbi__uint16 *dequant)
{
int diff,dc,k;
int t;
@@ -2692,7 +2611,7 @@ static stbi_uc stbi__get_marker(stbi__jpeg *j)
x = stbi__get8(j->s);
if (x != 0xff) return STBI__MARKER_none;
while (x == 0xff)
- x = stbi__get8(j->s);
+ x = stbi__get8(j->s); // consume repeated 0xff fill bytes
return x;
}
@@ -2707,7 +2626,7 @@ static void stbi__jpeg_reset(stbi__jpeg *j)
j->code_bits = 0;
j->code_buffer = 0;
j->nomore = 0;
- j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0;
+ j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = j->img_comp[3].dc_pred = 0;
j->marker = STBI__MARKER_none;
j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff;
j->eob_run = 0;
@@ -2839,7 +2758,7 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
}
}
-static void stbi__jpeg_dequantize(short *data, stbi_uc *dequant)
+static void stbi__jpeg_dequantize(short *data, stbi__uint16 *dequant)
{
int i;
for (i=0; i < 64; ++i)
@@ -2881,13 +2800,14 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
L = stbi__get16be(z->s)-2;
while (L > 0) {
int q = stbi__get8(z->s);
- int p = q >> 4;
+ int p = q >> 4, sixteen = (p != 0);
int t = q & 15,i;
- if (p != 0) return stbi__err("bad DQT type","Corrupt JPEG");
+ if (p != 0 && p != 1) return stbi__err("bad DQT type","Corrupt JPEG");
if (t > 3) return stbi__err("bad DQT table","Corrupt JPEG");
+
for (i=0; i < 64; ++i)
- z->dequant[t][stbi__jpeg_dezigzag[i]] = stbi__get8(z->s);
- L -= 65;
+ z->dequant[t][stbi__jpeg_dezigzag[i]] = sixteen ? stbi__get16be(z->s) : stbi__get8(z->s);
+ L -= (sixteen ? 129 : 65);
}
return L==0;
@@ -2920,12 +2840,50 @@ static int stbi__process_marker(stbi__jpeg *z, int m)
}
return L==0;
}
+
// check for comment block or APP blocks
if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) {
- stbi__skip(z->s, stbi__get16be(z->s)-2);
+ L = stbi__get16be(z->s);
+ if (L < 2) {
+ if (m == 0xFE)
+ return stbi__err("bad COM len","Corrupt JPEG");
+ else
+ return stbi__err("bad APP len","Corrupt JPEG");
+ }
+ L -= 2;
+
+ if (m == 0xE0 && L >= 5) { // JFIF APP0 segment
+ static const unsigned char tag[5] = {'J','F','I','F','\0'};
+ int ok = 1;
+ int i;
+ for (i=0; i < 5; ++i)
+ if (stbi__get8(z->s) != tag[i])
+ ok = 0;
+ L -= 5;
+ if (ok)
+ z->jfif = 1;
+ } else if (m == 0xEE && L >= 12) { // Adobe APP14 segment
+ static const unsigned char tag[6] = {'A','d','o','b','e','\0'};
+ int ok = 1;
+ int i;
+ for (i=0; i < 6; ++i)
+ if (stbi__get8(z->s) != tag[i])
+ ok = 0;
+ L -= 6;
+ if (ok) {
+ stbi__get8(z->s); // version
+ stbi__get16be(z->s); // flags0
+ stbi__get16be(z->s); // flags1
+ z->app14_color_transform = stbi__get8(z->s); // color transform
+ L -= 6;
+ }
+ }
+
+ stbi__skip(z->s, L);
return 1;
}
- return 0;
+
+ return stbi__err("unknown marker","Corrupt JPEG");
}
// after we see SOS
@@ -2999,7 +2957,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
c = stbi__get8(s);
- if (c != 3 && c != 1) return stbi__err("bad component count","Corrupt JPEG"); // JFIF requires
+ if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
s->img_n = c;
for (i=0; i < c; ++i) {
z->img_comp[i].data = NULL;
@@ -3012,13 +2970,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
for (i=0; i < s->img_n; ++i) {
static unsigned char rgb[3] = { 'R', 'G', 'B' };
z->img_comp[i].id = stbi__get8(s);
- if (z->img_comp[i].id != i+1) // JFIF requires
- if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files!
- // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format)
- if (z->img_comp[i].id != rgb[i])
- return stbi__err("bad component ID","Corrupt JPEG");
- ++z->rgb;
- }
+ if (s->img_n == 3 && z->img_comp[i].id == rgb[i])
+ ++z->rgb;
q = stbi__get8(s);
z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
@@ -3090,6 +3043,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
{
int m;
+ z->jfif = 0;
+ z->app14_color_transform = -1; // valid values are 0,1,2
z->marker = STBI__MARKER_none; // initialize cached marker to empty
m = stbi__get_marker(z);
if (!stbi__SOI(m)) return stbi__err("no SOI","Corrupt JPEG");
@@ -3131,12 +3086,15 @@ static int stbi__decode_jpeg_image(stbi__jpeg *j)
if (x == 255) {
j->marker = stbi__get8(j->s);
break;
- } else if (x != 0) {
- return stbi__err("junk before marker", "Corrupt JPEG");
}
}
// if we reach eof without hitting a marker, stbi__get_marker() below will fail and we'll eventually return 0
}
+ } else if (stbi__DNL(m)) {
+ int Ld = stbi__get16be(j->s);
+ stbi__uint32 NL = stbi__get16be(j->s);
+ if (Ld != 4) stbi__err("bad DNL len", "Corrupt JPEG");
+ if (NL != j->s->img_y) stbi__err("bad DNL height", "Corrupt JPEG");
} else {
if (!stbi__process_marker(j, m)) return 0;
}
@@ -3355,38 +3313,9 @@ static stbi_uc *stbi__resample_row_generic(stbi_uc *out, stbi_uc *in_near, stbi_
return out;
}
-#ifdef STBI_JPEG_OLD
-// this is the same YCbCr-to-RGB calculation that stb_image has used
-// historically before the algorithm changes in 1.49
-#define float2fixed(x) ((int) ((x) * 65536 + 0.5))
-static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
-{
- int i;
- for (i=0; i < count; ++i) {
- int y_fixed = (y[i] << 16) + 32768; // rounding
- int r,g,b;
- int cr = pcr[i] - 128;
- int cb = pcb[i] - 128;
- r = y_fixed + cr*float2fixed(1.40200f);
- g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f);
- b = y_fixed + cb*float2fixed(1.77200f);
- r >>= 16;
- g >>= 16;
- b >>= 16;
- if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; }
- if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; }
- if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; }
- out[0] = (stbi_uc)r;
- out[1] = (stbi_uc)g;
- out[2] = (stbi_uc)b;
- out[3] = 255;
- out += step;
- }
-}
-#else
// this is a reduced-precision calculation of YCbCr-to-RGB introduced
// to make sure the code produces the same results in both SIMD and scalar
-#define float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
+#define stbi__float2fixed(x) (((int) ((x) * 4096.0f + 0.5f)) << 8)
static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc *pcb, const stbi_uc *pcr, int count, int step)
{
int i;
@@ -3395,9 +3324,9 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
int r,g,b;
int cr = pcr[i] - 128;
int cb = pcb[i] - 128;
- r = y_fixed + cr* float2fixed(1.40200f);
- g = y_fixed + (cr*-float2fixed(0.71414f)) + ((cb*-float2fixed(0.34414f)) & 0xffff0000);
- b = y_fixed + cb* float2fixed(1.77200f);
+ r = y_fixed + cr* stbi__float2fixed(1.40200f);
+ g = y_fixed + (cr*-stbi__float2fixed(0.71414f)) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
+ b = y_fixed + cb* stbi__float2fixed(1.77200f);
r >>= 20;
g >>= 20;
b >>= 20;
@@ -3411,7 +3340,6 @@ static void stbi__YCbCr_to_RGB_row(stbi_uc *out, const stbi_uc *y, const stbi_uc
out += step;
}
}
-#endif
#if defined(STBI_SSE2) || defined(STBI_NEON)
static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc const *pcb, stbi_uc const *pcr, int count, int step)
@@ -3530,9 +3458,9 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
int r,g,b;
int cr = pcr[i] - 128;
int cb = pcb[i] - 128;
- r = y_fixed + cr* float2fixed(1.40200f);
- g = y_fixed + cr*-float2fixed(0.71414f) + ((cb*-float2fixed(0.34414f)) & 0xffff0000);
- b = y_fixed + cb* float2fixed(1.77200f);
+ r = y_fixed + cr* stbi__float2fixed(1.40200f);
+ g = y_fixed + cr*-stbi__float2fixed(0.71414f) + ((cb*-stbi__float2fixed(0.34414f)) & 0xffff0000);
+ b = y_fixed + cb* stbi__float2fixed(1.77200f);
r >>= 20;
g >>= 20;
b >>= 20;
@@ -3558,18 +3486,14 @@ static void stbi__setup_jpeg(stbi__jpeg *j)
#ifdef STBI_SSE2
if (stbi__sse2_available()) {
j->idct_block_kernel = stbi__idct_simd;
- #ifndef STBI_JPEG_OLD
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
- #endif
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
}
#endif
#ifdef STBI_NEON
j->idct_block_kernel = stbi__idct_simd;
- #ifndef STBI_JPEG_OLD
j->YCbCr_to_RGB_kernel = stbi__YCbCr_to_RGB_simd;
- #endif
j->resample_row_hv_2_kernel = stbi__resample_row_hv_2_simd;
#endif
}
@@ -3590,9 +3514,16 @@ typedef struct
int ypos; // which pre-expansion row we're on
} stbi__resample;
+// fast 0..255 * 0..255 => 0..255 rounded multiplication
+static stbi_uc stbi__blinn_8x8(stbi_uc x, stbi_uc y)
+{
+ unsigned int t = x*y + 128;
+ return (stbi_uc) ((t + (t >>8)) >> 8);
+}
+
static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp, int req_comp)
{
- int n, decode_n;
+ int n, decode_n, is_rgb;
z->s->img_n = 0; // make stbi__cleanup_jpeg safe
// validate req_comp
@@ -3602,9 +3533,11 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (!stbi__decode_jpeg_image(z)) { stbi__cleanup_jpeg(z); return NULL; }
// determine actual number of components to generate
- n = req_comp ? req_comp : z->s->img_n;
+ n = req_comp ? req_comp : z->s->img_n >= 3 ? 3 : 1;
- if (z->s->img_n == 3 && n < 3)
+ is_rgb = z->s->img_n == 3 && (z->rgb == 3 || (z->app14_color_transform == 0 && !z->jfif));
+
+ if (z->s->img_n == 3 && n < 3 && !is_rgb)
decode_n = 1;
else
decode_n = z->s->img_n;
@@ -3664,7 +3597,7 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (n >= 3) {
stbi_uc *y = coutput[0];
if (z->s->img_n == 3) {
- if (z->rgb == 3) {
+ if (is_rgb) {
for (i=0; i < z->s->img_x; ++i) {
out[0] = y[i];
out[1] = coutput[1][i];
@@ -3675,6 +3608,28 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
} else {
z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
}
+ } else if (z->s->img_n == 4) {
+ if (z->app14_color_transform == 0) { // CMYK
+ for (i=0; i < z->s->img_x; ++i) {
+ stbi_uc k = coutput[3][i];
+ out[0] = stbi__blinn_8x8(coutput[0][i], k);
+ out[1] = stbi__blinn_8x8(coutput[1][i], k);
+ out[2] = stbi__blinn_8x8(coutput[2][i], k);
+ out[3] = 255;
+ out += n;
+ }
+ } else if (z->app14_color_transform == 2) { // YCCK
+ z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+ for (i=0; i < z->s->img_x; ++i) {
+ stbi_uc k = coutput[3][i];
+ out[0] = stbi__blinn_8x8(255 - out[0], k);
+ out[1] = stbi__blinn_8x8(255 - out[1], k);
+ out[2] = stbi__blinn_8x8(255 - out[2], k);
+ out += n;
+ }
+ } else { // YCbCr + alpha? Ignore the fourth channel for now
+ z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+ }
} else
for (i=0; i < z->s->img_x; ++i) {
out[0] = out[1] = out[2] = y[i];
@@ -3682,17 +3637,45 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
out += n;
}
} else {
- stbi_uc *y = coutput[0];
- if (n == 1)
- for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
- else
- for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
+ if (is_rgb) {
+ if (n == 1)
+ for (i=0; i < z->s->img_x; ++i)
+ *out++ = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
+ else {
+ for (i=0; i < z->s->img_x; ++i, out += 2) {
+ out[0] = stbi__compute_y(coutput[0][i], coutput[1][i], coutput[2][i]);
+ out[1] = 255;
+ }
+ }
+ } else if (z->s->img_n == 4 && z->app14_color_transform == 0) {
+ for (i=0; i < z->s->img_x; ++i) {
+ stbi_uc k = coutput[3][i];
+ stbi_uc r = stbi__blinn_8x8(coutput[0][i], k);
+ stbi_uc g = stbi__blinn_8x8(coutput[1][i], k);
+ stbi_uc b = stbi__blinn_8x8(coutput[2][i], k);
+ out[0] = stbi__compute_y(r, g, b);
+ out[1] = 255;
+ out += n;
+ }
+ } else if (z->s->img_n == 4 && z->app14_color_transform == 2) {
+ for (i=0; i < z->s->img_x; ++i) {
+ out[0] = stbi__blinn_8x8(255 - coutput[0][i], coutput[3][i]);
+ out[1] = 255;
+ out += n;
+ }
+ } else {
+ stbi_uc *y = coutput[0];
+ if (n == 1)
+ for (i=0; i < z->s->img_x; ++i) out[i] = y[i];
+ else
+ for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255;
+ }
}
}
stbi__cleanup_jpeg(z);
*out_x = z->s->img_x;
*out_y = z->s->img_y;
- if (comp) *comp = z->s->img_n; // report original components, not output
+ if (comp) *comp = z->s->img_n >= 3 ? 3 : 1; // report original components, not output
return output;
}
}
@@ -3701,6 +3684,7 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
{
unsigned char* result;
stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
+ STBI_NOTUSED(ri);
j->s = s;
stbi__setup_jpeg(j);
result = load_jpeg_image(j, x,y,comp,req_comp);
@@ -3711,11 +3695,12 @@ static void *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int re
static int stbi__jpeg_test(stbi__context *s)
{
int r;
- stbi__jpeg j;
- j.s = s;
- stbi__setup_jpeg(&j);
- r = stbi__decode_jpeg_header(&j, STBI__SCAN_type);
+ stbi__jpeg* j = (stbi__jpeg*)stbi__malloc(sizeof(stbi__jpeg));
+ j->s = s;
+ stbi__setup_jpeg(j);
+ r = stbi__decode_jpeg_header(j, STBI__SCAN_type);
stbi__rewind(s);
+ STBI_FREE(j);
return r;
}
@@ -3727,7 +3712,7 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
}
if (x) *x = j->s->img_x;
if (y) *y = j->s->img_y;
- if (comp) *comp = j->s->img_n;
+ if (comp) *comp = j->s->img_n >= 3 ? 3 : 1;
return 1;
}
@@ -3784,7 +3769,7 @@ stbi_inline static int stbi__bit_reverse(int v, int bits)
return stbi__bitreverse16(v) >> (16-bits);
}
-static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
+static int stbi__zbuild_huffman(stbi__zhuffman *z, const stbi_uc *sizelist, int num)
{
int i,k=0;
int code, next_code[16], sizes[17];
@@ -4074,9 +4059,24 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
return 1;
}
-// @TODO: should statically initialize these for optimal thread safety
-static stbi_uc stbi__zdefault_length[288], stbi__zdefault_distance[32];
-static void stbi__init_zdefaults(void)
+static const stbi_uc stbi__zdefault_length[288] =
+{
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8
+};
+static const stbi_uc stbi__zdefault_distance[32] =
+{
+ 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5
+};
+/*
+Init algorithm:
{
int i; // use <= to match clearly with spec
for (i=0; i <= 143; ++i) stbi__zdefault_length[i] = 8;
@@ -4086,6 +4086,7 @@ static void stbi__init_zdefaults(void)
for (i=0; i <= 31; ++i) stbi__zdefault_distance[i] = 5;
}
+*/
static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
{
@@ -4104,7 +4105,6 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
} else {
if (type == 1) {
// use fixed code lengths
- if (!stbi__zdefault_distance[31]) stbi__init_zdefaults();
if (!stbi__zbuild_huffman(&a->z_length , stbi__zdefault_length , 288)) return 0;
if (!stbi__zbuild_huffman(&a->z_distance, stbi__zdefault_distance, 32)) return 0;
} else {
@@ -4305,7 +4305,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
for (j=0; j < y; ++j) {
stbi_uc *cur = a->out + stride*j;
- stbi_uc *prior = cur - stride;
+ stbi_uc *prior;
int filter = *raw++;
if (filter > 4)
@@ -4317,6 +4317,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
filter_bytes = 1;
width = img_width_bytes;
}
+ prior = cur - stride; // bugfix: need to compute this after 'cur +=' computation above
// if first row, use special filter that doesn't sample previous row
if (j == 0) filter = first_row_filter[filter];
@@ -4709,7 +4710,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
- if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
+ if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
@@ -4992,7 +4993,7 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info->offset = stbi__get32le(s);
info->hsz = hsz = stbi__get32le(s);
info->mr = info->mg = info->mb = info->ma = 0;
-
+
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
if (hsz == 12) {
s->img_x = stbi__get16le(s);
@@ -5077,7 +5078,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi__bmp_data info;
STBI_NOTUSED(ri);
- info.all_a = 255;
+ info.all_a = 255;
if (stbi__bmp_parse_header(s, &info) == NULL)
return NULL; // error code already set
@@ -5196,7 +5197,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
stbi__skip(s, pad);
}
}
-
+
// if alpha channel is all 0s, replace with all 255s
if (target == 4 && all_a == 0)
for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
@@ -5979,9 +5980,11 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_comp, stbi__result_info *ri)
{
stbi_uc *result;
- int i, x,y;
+ int i, x,y, internal_comp;
STBI_NOTUSED(ri);
+ if (!comp) comp = &internal_comp;
+
for (i=0; i<92; ++i)
stbi__get8(s);
@@ -6600,6 +6603,11 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
char buffer[STBI__HDR_BUFLEN];
char *token;
int valid = 0;
+ int dummy;
+
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
if (stbi__hdr_test(s) == 0) {
stbi__rewind( s );
@@ -6641,14 +6649,14 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
void *p;
stbi__bmp_data info;
- info.all_a = 255;
+ info.all_a = 255;
p = stbi__bmp_parse_header(s, &info);
stbi__rewind( s );
if (p == NULL)
return 0;
- *x = s->img_x;
- *y = s->img_y;
- *comp = info.ma ? 4 : 3;
+ if (x) *x = s->img_x;
+ if (y) *y = s->img_y;
+ if (comp) *comp = info.ma ? 4 : 3;
return 1;
}
#endif
@@ -6656,7 +6664,10 @@ static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_PSD
static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
{
- int channelCount;
+ int channelCount, dummy;
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
if (stbi__get32be(s) != 0x38425053) {
stbi__rewind( s );
return 0;
@@ -6689,9 +6700,13 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_PIC
static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
{
- int act_comp=0,num_packets=0,chained;
+ int act_comp=0,num_packets=0,chained,dummy;
stbi__pic_packet packets[10];
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
+
if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
stbi__rewind(s);
return 0;
@@ -6777,7 +6792,7 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
*x = s->img_x;
*y = s->img_y;
- *comp = s->img_n;
+ if (comp) *comp = s->img_n;
if (!stbi__mad3sizes_valid(s->img_n, s->img_x, s->img_y, 0))
return stbi__errpuc("too large", "PNM too large");
@@ -6831,16 +6846,20 @@ static int stbi__pnm_getinteger(stbi__context *s, char *c)
static int stbi__pnm_info(stbi__context *s, int *x, int *y, int *comp)
{
- int maxv;
+ int maxv, dummy;
char c, p, t;
- stbi__rewind( s );
+ if (!x) x = &dummy;
+ if (!y) y = &dummy;
+ if (!comp) comp = &dummy;
+
+ stbi__rewind(s);
// Get identifier
p = (char) stbi__get8(s);
t = (char) stbi__get8(s);
if (p != 'P' || (t != '5' && t != '6')) {
- stbi__rewind( s );
+ stbi__rewind(s);
return 0;
}
@@ -6947,6 +6966,11 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/*
revision history:
+ 2.15 (2017-03-18) fix png-1,2,4 bug; now all Imagenet JPGs decode;
+ warning fixes; disable run-time SSE detection on gcc;
+ uniform handling of optional "return" values;
+ thread-safe initialization of zlib tables
+ 2.14 (2017-03-03) remove deprecated STBI_JPEG_OLD; fixes for Imagenet JPGs
2.13 (2016-11-29) add 16-bit API, only supported for PNG right now
2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
2.11 (2016-04-02) allocate large structures on the stack
@@ -7108,3 +7132,46 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
0.50 (2006-11-19)
first released version
*/
+
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+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.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/src/external/stb_image_resize.h b/src/external/stb_image_resize.h
index 5214ad6e..b507e049 100644
--- a/src/external/stb_image_resize.h
+++ b/src/external/stb_image_resize.h
@@ -1,4 +1,4 @@
-/* stb_image_resize - v0.92 - public domain image resizing
+/* stb_image_resize - v0.94 - public domain image resizing
by Jorge L Rodriguez (@VinoBS) - 2014
http://github.com/nothings/stb
@@ -107,8 +107,8 @@
industry, it is still uncommon in the videogame/real-time world.
If you linearly filter non-premultiplied alpha, strange effects
- occur. (For example, the average of 1% opaque bright green
- and 99% opaque black produces 50% transparent dark green when
+ occur. (For example, the 50/50 average of 99% transparent bright green
+ and 1% transparent black produces 50% transparent dark green when
non-premultiplied, whereas premultiplied it produces 50%
transparent near-black. The former introduces green energy
that doesn't exist in the source image.)
@@ -152,20 +152,20 @@
(For example, graphics hardware does not apply sRGB conversion
to the alpha channel.)
- ADDITIONAL CONTRIBUTORS
+ CONTRIBUTORS
+ Jorge L Rodriguez: Implementation
Sean Barrett: API design, optimizations
Aras Pranckevicius: bugfix
REVISIONS
+ 0.94 (2017-03-18) fixed warnings
+ 0.93 (2017-03-03) fixed bug with certain combinations of heights
0.92 (2017-01-02) fix integer overflow on large (>2GB) images
0.91 (2016-04-02) fix warnings; fix handling of subpixel regions
0.90 (2014-09-17) first released version
LICENSE
-
- This software is dual-licensed to the public domain and under the following
- license: you are granted a perpetual, irrevocable license to copy, modify,
- publish, and distribute this file as you see fit.
+ See end of file for license information.
TODO
Don't decode all of the image data when only processing a partial tile
@@ -533,10 +533,11 @@ typedef struct
int horizontal_num_contributors;
int vertical_num_contributors;
- int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter)
+ int ring_buffer_length_bytes; // The length of an individual entry in the ring buffer. The total number of ring buffers is stbir__get_filter_pixel_width(filter)
+ int ring_buffer_num_entries; // Total number of entries in the ring buffer.
int ring_buffer_first_scanline;
int ring_buffer_last_scanline;
- int ring_buffer_begin_index;
+ int ring_buffer_begin_index; // first_scanline is at this index in the ring buffer
float* ring_buffer;
float* encode_buffer; // A temporary buffer to store floats so we don't lose precision while we do multiply-adds.
@@ -551,16 +552,17 @@ typedef struct
int encode_buffer_size;
} stbir__info;
+
+static const float stbir__max_uint8_as_float = 255.0f;
+static const float stbir__max_uint16_as_float = 65535.0f;
+static const double stbir__max_uint32_as_float = 4294967295.0;
+
+
static stbir__inline int stbir__min(int a, int b)
{
return a < b ? a : b;
}
-static stbir__inline int stbir__max(int a, int b)
-{
- return a > b ? a : b;
-}
-
static stbir__inline float stbir__saturate(float x)
{
if (x < 0)
@@ -1027,7 +1029,7 @@ static void stbir__calculate_sample_range_downsample(int n, float in_pixels_radi
*out_last_pixel = (int)(floor(out_pixel_influence_upperbound - 0.5));
}
-static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group)
+static void stbir__calculate_coefficients_upsample(stbir_filter filter, float scale, int in_first_pixel, int in_last_pixel, float in_center_of_out, stbir__contributors* contributor, float* coefficient_group)
{
int i;
float total_filter = 0;
@@ -1077,7 +1079,7 @@ static void stbir__calculate_coefficients_upsample(stbir__info* stbir_info, stbi
}
}
-static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group)
+static void stbir__calculate_coefficients_downsample(stbir_filter filter, float scale_ratio, int out_first_pixel, int out_last_pixel, float out_center_of_in, stbir__contributors* contributor, float* coefficient_group)
{
int i;
@@ -1107,7 +1109,7 @@ static void stbir__calculate_coefficients_downsample(stbir__info* stbir_info, st
}
}
-static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
+static void stbir__normalize_downsample_coefficients(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, int input_size, int output_size)
{
int num_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size);
int num_coefficients = stbir__get_coefficient_width(filter, scale_ratio);
@@ -1184,7 +1186,7 @@ static void stbir__normalize_downsample_coefficients(stbir__info* stbir_info, st
// Each scan line uses the same kernel values so we should calculate the kernel
// values once and then we can use them for every scan line.
-static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
+static void stbir__calculate_filters(stbir__contributors* contributors, float* coefficients, stbir_filter filter, float scale_ratio, float shift, int input_size, int output_size)
{
int n;
int total_contributors = stbir__get_contributors(scale_ratio, filter, input_size, output_size);
@@ -1201,7 +1203,7 @@ static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributor
stbir__calculate_sample_range_upsample(n, out_pixels_radius, scale_ratio, shift, &in_first_pixel, &in_last_pixel, &in_center_of_out);
- stbir__calculate_coefficients_upsample(stbir_info, filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
+ stbir__calculate_coefficients_upsample(filter, scale_ratio, in_first_pixel, in_last_pixel, in_center_of_out, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
}
}
else
@@ -1217,10 +1219,10 @@ static void stbir__calculate_filters(stbir__info* stbir_info, stbir__contributor
stbir__calculate_sample_range_downsample(n_adjusted, in_pixels_radius, scale_ratio, shift, &out_first_pixel, &out_last_pixel, &out_center_of_in);
- stbir__calculate_coefficients_downsample(stbir_info, filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
+ stbir__calculate_coefficients_downsample(filter, scale_ratio, out_first_pixel, out_last_pixel, out_center_of_in, stbir__get_contributor(contributors, n), stbir__get_coefficient(coefficients, filter, scale_ratio, n, 0));
}
- stbir__normalize_downsample_coefficients(stbir_info, contributors, coefficients, filter, scale_ratio, shift, input_size, output_size);
+ stbir__normalize_downsample_coefficients(contributors, coefficients, filter, scale_ratio, input_size, output_size);
}
}
@@ -1270,7 +1272,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
- decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / 255;
+ decode_buffer[decode_pixel_index + c] = ((float)((const unsigned char*)input_data)[input_pixel_index + c]) / stbir__max_uint8_as_float;
}
break;
@@ -1283,7 +1285,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
decode_buffer[decode_pixel_index + c] = stbir__srgb_uchar_to_linear_float[((const unsigned char*)input_data)[input_pixel_index + c]];
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
- decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / 255;
+ decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned char*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint8_as_float;
}
break;
@@ -1293,7 +1295,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
- decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535;
+ decode_buffer[decode_pixel_index + c] = ((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float;
}
break;
@@ -1303,10 +1305,10 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
- decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / 65535);
+ decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear(((float)((const unsigned short*)input_data)[input_pixel_index + c]) / stbir__max_uint16_as_float);
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
- decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / 65535;
+ decode_buffer[decode_pixel_index + alpha_channel] = ((float)((const unsigned short*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint16_as_float;
}
break;
@@ -1316,7 +1318,7 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
- decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295);
+ decode_buffer[decode_pixel_index + c] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float);
}
break;
@@ -1326,10 +1328,10 @@ static void stbir__decode_scanline(stbir__info* stbir_info, int n)
int decode_pixel_index = x * channels;
int input_pixel_index = stbir__edge_wrap(edge_horizontal, x, input_w) * channels;
for (c = 0; c < channels; c++)
- decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / 4294967295));
+ decode_buffer[decode_pixel_index + c] = stbir__srgb_to_linear((float)(((double)((const unsigned int*)input_data)[input_pixel_index + c]) / stbir__max_uint32_as_float));
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
- decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / 4294967295);
+ decode_buffer[decode_pixel_index + alpha_channel] = (float)(((double)((const unsigned int*)input_data)[input_pixel_index + alpha_channel]) / stbir__max_uint32_as_float);
}
break;
@@ -1411,6 +1413,8 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n)
int ring_buffer_index;
float* ring_buffer;
+ stbir_info->ring_buffer_last_scanline = n;
+
if (stbir_info->ring_buffer_begin_index < 0)
{
ring_buffer_index = stbir_info->ring_buffer_begin_index = 0;
@@ -1418,24 +1422,21 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info, int n)
}
else
{
- ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline) + 1) % stbir_info->vertical_filter_pixel_width;
+ ring_buffer_index = (stbir_info->ring_buffer_begin_index + (stbir_info->ring_buffer_last_scanline - stbir_info->ring_buffer_first_scanline)) % stbir_info->ring_buffer_num_entries;
STBIR_ASSERT(ring_buffer_index != stbir_info->ring_buffer_begin_index);
}
ring_buffer = stbir__get_ring_buffer_entry(stbir_info->ring_buffer, ring_buffer_index, stbir_info->ring_buffer_length_bytes / sizeof(float));
memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes);
- stbir_info->ring_buffer_last_scanline = n;
-
return ring_buffer;
}
-static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n, float* output_buffer)
+static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, float* output_buffer)
{
int x, k;
int output_w = stbir_info->output_w;
- int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width;
int channels = stbir_info->channels;
float* decode_buffer = stbir__get_decode_buffer(stbir_info);
stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors;
@@ -1515,12 +1516,10 @@ static void stbir__resample_horizontal_upsample(stbir__info* stbir_info, int n,
}
}
-static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, int n, float* output_buffer)
+static void stbir__resample_horizontal_downsample(stbir__info* stbir_info, float* output_buffer)
{
int x, k;
int input_w = stbir_info->input_w;
- int output_w = stbir_info->output_w;
- int kernel_pixel_width = stbir_info->horizontal_filter_pixel_width;
int channels = stbir_info->channels;
float* decode_buffer = stbir__get_decode_buffer(stbir_info);
stbir__contributors* horizontal_contributors = stbir_info->horizontal_contributors;
@@ -1654,9 +1653,9 @@ static void stbir__decode_and_resample_upsample(stbir__info* stbir_info, int n)
// Now resample it into the ring buffer.
if (stbir__use_width_upsampling(stbir_info))
- stbir__resample_horizontal_upsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n));
+ stbir__resample_horizontal_upsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n));
else
- stbir__resample_horizontal_downsample(stbir_info, n, stbir__add_empty_ring_buffer_entry(stbir_info, n));
+ stbir__resample_horizontal_downsample(stbir_info, stbir__add_empty_ring_buffer_entry(stbir_info, n));
// Now it's sitting in the ring buffer ready to be used as source for the vertical sampling.
}
@@ -1670,17 +1669,17 @@ static void stbir__decode_and_resample_downsample(stbir__info* stbir_info, int n
// Now resample it into the horizontal buffer.
if (stbir__use_width_upsampling(stbir_info))
- stbir__resample_horizontal_upsample(stbir_info, n, stbir_info->horizontal_buffer);
+ stbir__resample_horizontal_upsample(stbir_info, stbir_info->horizontal_buffer);
else
- stbir__resample_horizontal_downsample(stbir_info, n, stbir_info->horizontal_buffer);
+ stbir__resample_horizontal_downsample(stbir_info, stbir_info->horizontal_buffer);
// Now it's sitting in the horizontal buffer ready to be distributed into the ring buffers.
}
// Get the specified scan line from the ring buffer.
-static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_size, int ring_buffer_length)
+static float* stbir__get_ring_buffer_scanline(int get_scanline, float* ring_buffer, int begin_index, int first_scanline, int ring_buffer_num_entries, int ring_buffer_length)
{
- int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_size;
+ int ring_buffer_index = (begin_index + (get_scanline - first_scanline)) % ring_buffer_num_entries;
return stbir__get_ring_buffer_entry(ring_buffer, ring_buffer_index, ring_buffer_length);
}
@@ -1715,19 +1714,23 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
// build a table of all channels that need colorspace correction, so
// we don't perform colorspace correction on channels that don't need it.
- for (x=0, num_nonalpha=0; x < channels; ++x)
+ for (x = 0, num_nonalpha = 0; x < channels; ++x)
+ {
if (x != alpha_channel || (stbir_info->flags & STBIR_FLAG_ALPHA_USES_COLORSPACE))
- nonalpha[num_nonalpha++] = x;
+ {
+ nonalpha[num_nonalpha++] = (stbir_uint16)x;
+ }
+ }
#define STBIR__ROUND_INT(f) ((int) ((f)+0.5))
#define STBIR__ROUND_UINT(f) ((stbir_uint32) ((f)+0.5))
#ifdef STBIR__SATURATE_INT
- #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * 255 ))
- #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * 65535))
+ #define STBIR__ENCODE_LINEAR8(f) stbir__saturate8 (STBIR__ROUND_INT((f) * stbir__max_uint8_as_float ))
+ #define STBIR__ENCODE_LINEAR16(f) stbir__saturate16(STBIR__ROUND_INT((f) * stbir__max_uint16_as_float))
#else
- #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * 255 )
- #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * 65535)
+ #define STBIR__ENCODE_LINEAR8(f) (unsigned char ) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint8_as_float )
+ #define STBIR__ENCODE_LINEAR16(f) (unsigned short) STBIR__ROUND_INT(stbir__saturate(f) * stbir__max_uint16_as_float)
#endif
switch (decode)
@@ -1782,7 +1785,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
for (n = 0; n < num_nonalpha; n++)
{
int index = pixel_index + nonalpha[n];
- ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * 65535);
+ ((unsigned short*)output_buffer)[index] = (unsigned short)STBIR__ROUND_INT(stbir__linear_to_srgb(stbir__saturate(encode_buffer[index])) * stbir__max_uint16_as_float);
}
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
@@ -1799,7 +1802,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
for (n = 0; n < channels; n++)
{
int index = pixel_index + n;
- ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * 4294967295);
+ ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__saturate(encode_buffer[index])) * stbir__max_uint32_as_float);
}
}
break;
@@ -1812,11 +1815,11 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
for (n = 0; n < num_nonalpha; n++)
{
int index = pixel_index + nonalpha[n];
- ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * 4294967295);
+ ((unsigned int*)output_buffer)[index] = (unsigned int)STBIR__ROUND_UINT(((double)stbir__linear_to_srgb(stbir__saturate(encode_buffer[index]))) * stbir__max_uint32_as_float);
}
if (!(stbir_info->flags&STBIR_FLAG_ALPHA_USES_COLORSPACE))
- ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * 4294967295);
+ ((unsigned int*)output_buffer)[pixel_index + alpha_channel] = (unsigned int)STBIR__ROUND_INT(((double)stbir__saturate(encode_buffer[pixel_index + alpha_channel])) * stbir__max_uint32_as_float);
}
break;
@@ -1855,7 +1858,7 @@ static void stbir__encode_scanline(stbir__info* stbir_info, int num_pixels, void
}
}
-static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out)
+static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n)
{
int x, k;
int output_w = stbir_info->output_w;
@@ -1865,7 +1868,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
int alpha_channel = stbir_info->alpha_channel;
int type = stbir_info->type;
int colorspace = stbir_info->colorspace;
- int kernel_pixel_width = stbir_info->vertical_filter_pixel_width;
+ int ring_buffer_entries = stbir_info->ring_buffer_num_entries;
void* output_data = stbir_info->output_data;
float* encode_buffer = stbir_info->encode_buffer;
int decode = STBIR__DECODE(type, colorspace);
@@ -1876,7 +1879,6 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
float* ring_buffer = stbir_info->ring_buffer;
int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index;
int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline;
- int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline;
int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float);
int n0,n1, output_row_start;
@@ -1900,7 +1902,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
- float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@@ -1913,7 +1915,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
- float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@@ -1927,7 +1929,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
- float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@@ -1942,7 +1944,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
- float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@@ -1958,7 +1960,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
for (k = n0; k <= n1; k++)
{
int coefficient_index = coefficient_counter++;
- float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
for (x = 0; x < output_w; ++x)
{
@@ -1973,16 +1975,14 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n, in
stbir__encode_scanline(stbir_info, output_w, (char *) output_data + output_row_start, encode_buffer, channels, alpha_channel, decode);
}
-static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n, int in_first_scanline, int in_last_scanline, float in_center_of_out)
+static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n)
{
int x, k;
int output_w = stbir_info->output_w;
- int output_h = stbir_info->output_h;
stbir__contributors* vertical_contributors = stbir_info->vertical_contributors;
float* vertical_coefficients = stbir_info->vertical_coefficients;
int channels = stbir_info->channels;
- int kernel_pixel_width = stbir_info->vertical_filter_pixel_width;
- void* output_data = stbir_info->output_data;
+ int ring_buffer_entries = stbir_info->ring_buffer_num_entries;
float* horizontal_buffer = stbir_info->horizontal_buffer;
int coefficient_width = stbir_info->vertical_coefficient_width;
int contributor = n + stbir_info->vertical_filter_pixel_margin;
@@ -1990,7 +1990,6 @@ static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n,
float* ring_buffer = stbir_info->ring_buffer;
int ring_buffer_begin_index = stbir_info->ring_buffer_begin_index;
int ring_buffer_first_scanline = stbir_info->ring_buffer_first_scanline;
- int ring_buffer_last_scanline = stbir_info->ring_buffer_last_scanline;
int ring_buffer_length = stbir_info->ring_buffer_length_bytes/sizeof(float);
int n0,n1;
@@ -2005,7 +2004,7 @@ static void stbir__resample_vertical_downsample(stbir__info* stbir_info, int n,
int coefficient_group = coefficient_width * contributor;
float coefficient = vertical_coefficients[coefficient_group + coefficient_index];
- float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, kernel_pixel_width, ring_buffer_length);
+ float* ring_buffer_entry = stbir__get_ring_buffer_scanline(k, ring_buffer, ring_buffer_begin_index, ring_buffer_first_scanline, ring_buffer_entries, ring_buffer_length);
switch (channels) {
case 1:
@@ -2071,7 +2070,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
stbir__calculate_sample_range_upsample(y, out_scanlines_radius, scale_ratio, stbir_info->vertical_shift, &in_first_scanline, &in_last_scanline, &in_center_of_out);
- STBIR_ASSERT(in_last_scanline - in_first_scanline <= stbir_info->vertical_filter_pixel_width);
+ STBIR_ASSERT(in_last_scanline - in_first_scanline + 1 <= stbir_info->ring_buffer_num_entries);
if (stbir_info->ring_buffer_begin_index >= 0)
{
@@ -2090,7 +2089,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
else
{
stbir_info->ring_buffer_first_scanline++;
- stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width;
+ stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries;
}
}
}
@@ -2103,7 +2102,7 @@ static void stbir__buffer_loop_upsample(stbir__info* stbir_info)
stbir__decode_and_resample_upsample(stbir_info, stbir_info->ring_buffer_last_scanline + 1);
// Now all buffers should be ready to write a row of vertical sampling.
- stbir__resample_vertical_upsample(stbir_info, y, in_first_scanline, in_last_scanline, in_center_of_out);
+ stbir__resample_vertical_upsample(stbir_info, y);
STBIR_PROGRESS_REPORT((float)y / stbir_info->output_h);
}
@@ -2148,7 +2147,7 @@ static void stbir__empty_ring_buffer(stbir__info* stbir_info, int first_necessar
else
{
stbir_info->ring_buffer_first_scanline++;
- stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->vertical_filter_pixel_width;
+ stbir_info->ring_buffer_begin_index = (stbir_info->ring_buffer_begin_index + 1) % stbir_info->ring_buffer_num_entries;
}
}
}
@@ -2172,7 +2171,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
stbir__calculate_sample_range_downsample(y, in_pixels_radius, scale_ratio, stbir_info->vertical_shift, &out_first_scanline, &out_last_scanline, &out_center_of_in);
- STBIR_ASSERT(out_last_scanline - out_first_scanline <= stbir_info->vertical_filter_pixel_width);
+ STBIR_ASSERT(out_last_scanline - out_first_scanline + 1 <= stbir_info->ring_buffer_num_entries);
if (out_last_scanline < 0 || out_first_scanline >= output_h)
continue;
@@ -2189,7 +2188,7 @@ static void stbir__buffer_loop_downsample(stbir__info* stbir_info)
stbir__add_empty_ring_buffer_entry(stbir_info, stbir_info->ring_buffer_last_scanline + 1);
// Now the horizontal buffer is ready to write to all ring buffer rows.
- stbir__resample_vertical_downsample(stbir_info, y, out_first_scanline, out_last_scanline, out_center_of_in);
+ stbir__resample_vertical_downsample(stbir_info, y);
}
stbir__empty_ring_buffer(stbir_info, stbir_info->output_h);
@@ -2246,13 +2245,16 @@ static stbir_uint32 stbir__calculate_memory(stbir__info *info)
info->horizontal_num_contributors = stbir__get_contributors(info->horizontal_scale, info->horizontal_filter, info->input_w, info->output_w);
info->vertical_num_contributors = stbir__get_contributors(info->vertical_scale , info->vertical_filter , info->input_h, info->output_h);
+ // One extra entry because floating point precision problems sometimes cause an extra to be necessary.
+ info->ring_buffer_num_entries = filter_height + 1;
+
info->horizontal_contributors_size = info->horizontal_num_contributors * sizeof(stbir__contributors);
info->horizontal_coefficients_size = stbir__get_total_horizontal_coefficients(info) * sizeof(float);
info->vertical_contributors_size = info->vertical_num_contributors * sizeof(stbir__contributors);
info->vertical_coefficients_size = stbir__get_total_vertical_coefficients(info) * sizeof(float);
info->decode_buffer_size = (info->input_w + pixel_margin * 2) * info->channels * sizeof(float);
info->horizontal_buffer_size = info->output_w * info->channels * sizeof(float);
- info->ring_buffer_size = info->output_w * info->channels * filter_height * sizeof(float);
+ info->ring_buffer_size = info->output_w * info->channels * info->ring_buffer_num_entries * sizeof(float);
info->encode_buffer_size = info->output_w * info->channels * sizeof(float);
STBIR_ASSERT(info->horizontal_filter != 0);
@@ -2390,8 +2392,8 @@ static int stbir__resize_allocated(stbir__info *info,
// This signals that the ring buffer is empty
info->ring_buffer_begin_index = -1;
- stbir__calculate_filters(info, info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w);
- stbir__calculate_filters(info, info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h);
+ stbir__calculate_filters(info->horizontal_contributors, info->horizontal_coefficients, info->horizontal_filter, info->horizontal_scale, info->horizontal_shift, info->input_w, info->output_w);
+ stbir__calculate_filters(info->vertical_contributors, info->vertical_coefficients, info->vertical_filter, info->vertical_scale, info->vertical_shift, info->input_h, info->output_h);
STBIR_PROGRESS_REPORT(0);
@@ -2578,3 +2580,45 @@ STBIRDEF int stbir_resize_region( const void *input_pixels , int input_w , int
}
#endif // STB_IMAGE_RESIZE_IMPLEMENTATION
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+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.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/src/external/stb_image_write.h b/src/external/stb_image_write.h
index ae9180b0..df623393 100644
--- a/src/external/stb_image_write.h
+++ b/src/external/stb_image_write.h
@@ -1,4 +1,4 @@
-/* stb_image_write - v1.03 - public domain - http://nothings.org/stb/stb_image_write.h
+/* stb_image_write - v1.05 - public domain - http://nothings.org/stb/stb_image_write.h
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk
@@ -104,12 +104,11 @@ CREDITS:
Filip Wasil
Thatcher Ulrich
github:poppolopoppo
+ Patrick Boettcher
LICENSE
-This software is dual-licensed to the public domain and under the following
-license: you are granted a perpetual, irrevocable license to copy, modify,
-publish, and distribute this file as you see fit.
+ See end of file for license information.
*/
@@ -294,10 +293,8 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
s->func(s->context, &d[comp - 1], 1);
switch (comp) {
+ case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
case 1:
- s->func(s->context,d,1);
- break;
- case 2:
if (expand_mono)
stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
else
@@ -897,6 +894,7 @@ static unsigned char stbiw__paeth(int a, int b, int c)
return STBIW_UCHAR(c);
}
+// @OPTIMIZE: provide an option that always forces left-predict or paeth predict
unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
{
int ctype[5] = { -1, 0, 4, 2, 6 };
@@ -913,10 +911,10 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
for (j=0; j < y; ++j) {
static int mapping[] = { 0,1,2,3,4 };
static int firstmap[] = { 0,1,0,5,6 };
- int *mymap = j ? mapping : firstmap;
+ int *mymap = (j != 0) ? mapping : firstmap;
int best = 0, bestval = 0x7fffffff;
for (p=0; p < 2; ++p) {
- for (k= p?best:0; k < 5; ++k) {
+ for (k= p?best:0; k < 5; ++k) { // @TODO: clarity: rewrite this to go 0..5, and 'continue' the unwanted ones during 2nd pass
int type = mymap[k],est=0;
unsigned char *z = pixels + stride_bytes*j;
for (i=0; i < n; ++i)
@@ -1018,6 +1016,9 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x,
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
/* Revision history
+ 1.04 (2017-03-03)
+ monochrome BMP expansion
+ 1.03 ???
1.02 (2016-04-02)
avoid allocating large structures on the stack
1.01 (2016-01-16)
@@ -1047,3 +1048,45 @@ STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x,
first public release
0.90 first internal release
*/
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+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.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/src/external/stb_rect_pack.h b/src/external/stb_rect_pack.h
index c75527da..f5eb8d33 100644
--- a/src/external/stb_rect_pack.h
+++ b/src/external/stb_rect_pack.h
@@ -1,4 +1,4 @@
-// stb_rect_pack.h - v0.10 - public domain - rectangle packing
+// stb_rect_pack.h - v0.11 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
@@ -27,11 +27,14 @@
// Sean Barrett
// Minor features
// Martins Mozeiko
+// github:IntellectualKitty
+//
// Bugfixes / warning fixes
// Jeremy Jaussaud
//
// Version history:
//
+// 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
// 0.09 (2016-08-27) fix compiler warnings
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
@@ -43,9 +46,7 @@
//
// LICENSE
//
-// This software is dual-licensed to the public domain and under the following
-// license: you are granted a perpetual, irrevocable license to copy, modify,
-// publish, and distribute this file as you see fit.
+// See end of file for license information.
//////////////////////////////////////////////////////////////////////////////
//
@@ -77,7 +78,7 @@ typedef int stbrp_coord;
typedef unsigned short stbrp_coord;
#endif
-STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
+STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
// Assign packed locations to rectangles. The rectangles are of type
// 'stbrp_rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
@@ -98,6 +99,9 @@ STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int
// arrays will probably produce worse packing results than calling it
// a single time with the full rectangle array, but the option is
// available.
+//
+// The function returns 1 if all of the rectangles were successfully
+// packed and 0 otherwise.
struct stbrp_rect
{
@@ -544,9 +548,9 @@ static int rect_original_order(const void *a, const void *b)
#define STBRP__MAXVAL 0xffff
#endif
-STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
+STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
- int i;
+ int i, all_rects_packed = 1;
// we use the 'was_packed' field internally to allow sorting/unsorting
for (i=0; i < num_rects; ++i) {
@@ -576,8 +580,56 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
// unsort
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
- // set was_packed flags
- for (i=0; i < num_rects; ++i)
+ // set was_packed flags and all_rects_packed status
+ for (i=0; i < num_rects; ++i) {
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
+ if (!rects[i].was_packed)
+ all_rects_packed = 0;
+ }
+
+ // return the all_rects_packed status
+ return all_rects_packed;
}
#endif
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+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.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/src/external/stb_truetype.h b/src/external/stb_truetype.h
index 92b9a875..fc5b9782 100644
--- a/src/external/stb_truetype.h
+++ b/src/external/stb_truetype.h
@@ -1,4 +1,4 @@
-// stb_truetype.h - v1.14 - public domain
+// stb_truetype.h - v1.15 - public domain
// authored from 2009-2016 by Sean Barrett / RAD Game Tools
//
// This library processes TrueType files:
@@ -50,10 +50,13 @@
// Higor Euripedes
// Thomas Fields
// Derek Vinyard
+// Cort Stratton
//
// VERSION HISTORY
//
-// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts, num-fonts-in-TTC function
+// 1.15 (2017-03-03) make more arguments const
+// 1.14 (2017-01-16) num-fonts-in-TTC function
+// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts
// 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual
// 1.11 (2016-04-02) fix unused-variable warning
// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
@@ -69,9 +72,7 @@
//
// LICENSE
//
-// This software is dual-licensed to the public domain and under the following
-// license: you are granted a perpetual, irrevocable license to copy, modify,
-// publish, and distribute this file as you see fit.
+// See end of file for license information.
//
// USAGE
//
@@ -494,7 +495,7 @@ typedef struct
float x1,y1,s1,t1; // bottom-right
} stbtt_aligned_quad;
-STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above
+STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display
float *xpos, float *ypos, // pointers to current position in screen pixel space
stbtt_aligned_quad *q, // output: quad to draw
@@ -594,7 +595,7 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
// To use with PackFontRangesGather etc., you must set it before calls
// call to PackFontRangesGatherRects.
-STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above
+STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
int char_index, // character to display
float *xpos, float *ypos, // pointers to current position in screen pixel space
stbtt_aligned_quad *q, // output: quad to draw
@@ -3287,11 +3288,11 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // fo
return bottom_y;
}
-STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
+STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule)
{
float d3d_bias = opengl_fillrule ? 0 : -0.5f;
float ipw = 1.0f / pw, iph = 1.0f / ph;
- stbtt_bakedchar *b = chardata + char_index;
+ const stbtt_bakedchar *b = chardata + char_index;
int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f);
int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f);
@@ -3735,10 +3736,10 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontda
return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
}
-STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
+STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
{
float ipw = 1.0f / pw, iph = 1.0f / ph;
- stbtt_packedchar *b = chardata + char_index;
+ const stbtt_packedchar *b = chardata + char_index;
if (align_to_integer) {
float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f);
@@ -4016,3 +4017,45 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const
// 0.2 (2009-03-11) Fix unsigned/signed char warnings
// 0.1 (2009-03-09) First public release
//
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+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.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/src/external/stb_vorbis.c b/src/external/stb_vorbis.c
index 07d79318..21638bcd 100644
--- a/src/external/stb_vorbis.c
+++ b/src/external/stb_vorbis.c
@@ -162,21 +162,23 @@
#endif
#ifndef STB_VORBIS_NO_CRT
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <math.h>
-#if !(defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh))
-#include <malloc.h>
-#if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)
-#include <alloca.h>
-#endif
-#endif
+ #include <stdlib.h>
+ #include <string.h>
+ #include <assert.h>
+ #include <math.h>
+
+ // find definition of alloca if it's not in stdlib.h:
+ #if defined(_MSC_VER) || defined(__MINGW32__)
+ #include <malloc.h>
+ #endif
+ #if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__)
+ #include <alloca.h>
+ #endif
#else // STB_VORBIS_NO_CRT
-#define NULL 0
-#define malloc(s) 0
-#define free(s) ((void) 0)
-#define realloc(s) 0
+ #define NULL 0
+ #define malloc(s) 0
+ #define free(s) ((void) 0)
+ #define realloc(s) 0
#endif // STB_VORBIS_NO_CRT
#include <limits.h>
@@ -597,17 +599,18 @@ static int ilog(int32 n)
{
static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 };
+ if (n < 0) return 0; // signed n returns 0
+
// 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29)
if (n < (1 << 14))
- if (n < (1 << 4)) return 0 + log2_4[n ];
- else if (n < (1 << 9)) return 5 + log2_4[n >> 5];
+ if (n < (1 << 4)) return 0 + log2_4[n ];
+ else if (n < (1 << 9)) return 5 + log2_4[n >> 5];
else return 10 + log2_4[n >> 10];
else if (n < (1 << 24))
- if (n < (1 << 19)) return 15 + log2_4[n >> 15];
+ if (n < (1 << 19)) return 15 + log2_4[n >> 15];
else return 20 + log2_4[n >> 20];
- else if (n < (1 << 29)) return 25 + log2_4[n >> 25];
- else if (n < (1 << 31)) return 30 + log2_4[n >> 30];
- else return 0; // signed n returns 0
+ else if (n < (1 << 29)) return 25 + log2_4[n >> 25];
+ else return 30 + log2_4[n >> 30];
}
#ifndef M_PI
@@ -880,13 +883,13 @@ static void neighbors(uint16 *x, int n, int *plow, int *phigh)
// this has been repurposed so y is now the original index instead of y
typedef struct
{
- uint16 x,y;
-} Point;
+ uint16 x,id;
+} stbv__floor_ordering;
static int STBV_CDECL point_compare(const void *p, const void *q)
{
- Point *a = (Point *) p;
- Point *b = (Point *) q;
+ stbv__floor_ordering *a = (stbv__floor_ordering *) p;
+ stbv__floor_ordering *b = (stbv__floor_ordering *) q;
return a->x < b->x ? -1 : a->x > b->x;
}
@@ -3095,11 +3098,13 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
return right - left;
}
-static void vorbis_pump_first_frame(stb_vorbis *f)
+static int vorbis_pump_first_frame(stb_vorbis *f)
{
- int len, right, left;
- if (vorbis_decode_packet(f, &len, &left, &right))
+ int len, right, left, res;
+ res = vorbis_decode_packet(f, &len, &left, &right);
+ if (res)
vorbis_finish_frame(f, len, left, right);
+ return res;
}
#ifndef STB_VORBIS_NO_PUSHDATA_API
@@ -3482,7 +3487,7 @@ static int start_decoder(vorb *f)
g->book_list[j] = get_bits(f,8);
return error(f, VORBIS_feature_not_supported);
} else {
- Point p[31*8+2];
+ stbv__floor_ordering p[31*8+2];
Floor1 *g = &f->floor_config[i].floor1;
int max_class = -1;
g->partitions = get_bits(f, 5);
@@ -3518,11 +3523,11 @@ static int start_decoder(vorb *f)
// precompute the sorting
for (j=0; j < g->values; ++j) {
p[j].x = g->Xlist[j];
- p[j].y = j;
+ p[j].id = j;
}
qsort(p, g->values, sizeof(p[0]), point_compare);
for (j=0; j < g->values; ++j)
- g->sorted_order[j] = (uint8) p[j].y;
+ g->sorted_order[j] = (uint8) p[j].id;
// precompute the neighbors
for (j=2; j < g->values; ++j) {
int low,hi;
@@ -4226,8 +4231,9 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
// starting from the start is handled differently
if (sample_number <= left.last_decoded_sample) {
- stb_vorbis_seek_start(f);
- return 1;
+ if (stb_vorbis_seek_start(f))
+ return 1;
+ return 0;
}
while (left.page_end != right.page_start) {
@@ -4328,7 +4334,10 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
skip(f, f->segments[i]);
// start decoding (optimizable - this frame is generally discarded)
- vorbis_pump_first_frame(f);
+ if (!vorbis_pump_first_frame(f))
+ return 0;
+ if (f->current_loc > sample_number)
+ return error(f, VORBIS_seek_failed);
return 1;
error:
@@ -4419,14 +4428,14 @@ int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number)
return 1;
}
-void stb_vorbis_seek_start(stb_vorbis *f)
+int stb_vorbis_seek_start(stb_vorbis *f)
{
- if (IS_PUSH_MODE(f)) { error(f, VORBIS_invalid_api_mixing); return; }
+ if (IS_PUSH_MODE(f)) { return error(f, VORBIS_invalid_api_mixing); }
set_file_offset(f, f->first_audio_page_offset);
f->previous_length = 0;
f->first_decode = TRUE;
f->next_seg = -1;
- vorbis_pump_first_frame(f);
+ return vorbis_pump_first_frame(f);
}
unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f)
@@ -4591,6 +4600,7 @@ stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *err
if (f) {
*f = p;
vorbis_pump_first_frame(f);
+ if (error) *error = VORBIS__no_error;
return f;
}
}
@@ -4956,6 +4966,7 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
#endif // STB_VORBIS_NO_PULLDATA_API
/* Version history
+ 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version
1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks;
avoid discarding last frame of audio data
@@ -5008,3 +5019,46 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
*/
#endif // STB_VORBIS_HEADER_ONLY
+
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+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.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/src/external/stb_vorbis.h b/src/external/stb_vorbis.h
index 624ce4bc..9394e813 100644
--- a/src/external/stb_vorbis.h
+++ b/src/external/stb_vorbis.h
@@ -1,4 +1,4 @@
-// Ogg Vorbis audio decoder - v1.09 - public domain
+// Ogg Vorbis audio decoder - v1.10 - public domain
// http://nothings.org/stb_vorbis/
//
// Original version written by Sean Barrett in 2007.
@@ -9,12 +9,7 @@
//
// LICENSE
//
-// This software is dual-licensed to the public domain and under the following
-// license: you are granted a perpetual, irrevocable license to copy, modify,
-// publish, and distribute this file as you see fit.
-//
-// No warranty for any purpose is expressed or implied by the author (nor
-// by RAD Game Tools). Report bugs and send enhancements to the author.
+// See end of file for license information.
//
// Limitations:
//
@@ -37,6 +32,7 @@
// manxorist@github saga musix
//
// Partial history:
+// 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory
// 1.09 - 2016/04/04 - back out 'truncation of last frame' fix from previous version
// 1.08 - 2016/04/02 - warnings; setup memory leaks; truncation of last frame
// 1.07 - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const
@@ -280,7 +276,7 @@ extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number);
// do not need to seek to EXACTLY the target sample when using get_samples_*,
// you can also use seek_frame().
-extern void stb_vorbis_seek_start(stb_vorbis *f);
+extern int stb_vorbis_seek_start(stb_vorbis *f);
// this function is equivalent to stb_vorbis_seek(f,0)
extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f);
diff --git a/src/gestures.h b/src/gestures.h
index 99f49d2a..f04bf091 100644
--- a/src/gestures.h
+++ b/src/gestures.h
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
-* raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse)
+* raylib.gestures - Gestures system, gestures processing based on input events (touch/mouse)
*
* NOTE: Memory footprint of this library is aproximately 128 bytes (global variables)
*
@@ -24,7 +24,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -147,7 +147,7 @@ float GetGesturePinchAngle(void); // Get gesture pinch ang
// 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)
+#elif defined(__linux__)
#include <sys/time.h> // Required for: timespec
#include <time.h> // Required for: clock_gettime()
#endif
@@ -213,8 +213,11 @@ static unsigned int enabledGestures = 0b0000001111111111;
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
+#if defined(GESTURES_STANDALONE)
+// Some required math functions provided by raymath.h
static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition);
static float Vector2Distance(Vector2 v1, Vector2 v2);
+#endif
static double GetCurrentTime(void);
//----------------------------------------------------------------------------------
@@ -477,13 +480,11 @@ float GetGesturePinchAngle(void)
//----------------------------------------------------------------------------------
// Module specific Functions Definition
//----------------------------------------------------------------------------------
-
+#if defined(GESTURES_STANDALONE)
// Returns angle from two-points vector with X-axis
-static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition)
+static float Vector2Angle(Vector2 v1, Vector2 v2)
{
- float angle;
-
- angle = atan2f(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI);
+ float angle = angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
if (angle < 0) angle += 360.0f;
@@ -502,6 +503,7 @@ static float Vector2Distance(Vector2 v1, Vector2 v2)
return result;
}
+#endif
// Time measure returned are milliseconds
static double GetCurrentTime(void)
@@ -517,7 +519,7 @@ static double GetCurrentTime(void)
time = (double)currentTime/clockFrequency*1000.0f; // Time in miliseconds
#endif
-#if defined(__linux)
+#if defined(__linux__)
// NOTE: Only for Linux-based systems
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
diff --git a/src/models.c b/src/models.c
index bef19e10..0a692f5c 100644
--- a/src/models.c
+++ b/src/models.c
@@ -1,17 +1,19 @@
/**********************************************************************************************
*
-* raylib.models - Basic functions to draw 3d shapes and 3d models
+* raylib.models - Basic functions to deal with 3d shapes and 3d models
*
* CONFIGURATION:
*
-* #define SUPPORT_FILEFORMAT_OBJ / SUPPORT_LOAD_OBJ
+* #define SUPPORT_FILEFORMAT_OBJ
+* Selected desired fileformats to be supported for loading.
*
* #define SUPPORT_FILEFORMAT_MTL
+* Selected desired fileformats to be supported for loading.
*
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -30,6 +32,12 @@
*
**********************************************************************************************/
+// Default configuration flags (supported features)
+//-------------------------------------------------
+#define SUPPORT_FILEFORMAT_OBJ
+#define SUPPORT_FILEFORMAT_MTL
+//-------------------------------------------------
+
#include "raylib.h"
#if defined(PLATFORM_ANDROID)
@@ -61,8 +69,12 @@
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_FILEFORMAT_OBJ)
static Mesh LoadOBJ(const char *fileName); // Load OBJ mesh data
+#endif
+#if defined(SUPPORT_FILEFORMAT_MTL)
static Material LoadMTL(const char *fileName); // Load MTL material data
+#endif
static Mesh GenMeshHeightmap(Image image, Vector3 size);
static Mesh GenMeshCubicmap(Image cubicmap, Vector3 cubeSize);
@@ -580,8 +592,11 @@ Mesh LoadMesh(const char *fileName)
{
Mesh mesh = { 0 };
- if (strcmp(GetExtension(fileName), "obj") == 0) mesh = LoadOBJ(fileName);
- else TraceLog(WARNING, "[%s] Mesh extension not recognized, it can't be loaded", fileName);
+#if defined(SUPPORT_FILEFORMAT_OBJ)
+ if (IsFileExtension(fileName, ".obj")) mesh = LoadOBJ(fileName);
+#else
+ TraceLog(WARNING, "[%s] Mesh fileformat not supported, it can't be loaded", fileName);
+#endif
if (mesh.vertexCount == 0) TraceLog(WARNING, "Mesh could not be loaded");
else rlglLoadMesh(&mesh, false); // Upload vertex data to GPU (static mesh)
@@ -592,13 +607,13 @@ Mesh LoadMesh(const char *fileName)
}
// Load mesh from vertex data
-// NOTE: All vertex data arrays must be same size: numVertex
-Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData)
+// NOTE: All vertex data arrays must be same size: vertexCount
+Mesh LoadMeshEx(int vertexCount, float *vData, float *vtData, float *vnData, Color *cData)
{
Mesh mesh = { 0 };
- mesh.vertexCount = numVertex;
- mesh.triangleCount = numVertex/3;
+ mesh.vertexCount = vertexCount;
+ mesh.triangleCount = vertexCount/3;
mesh.vertices = vData;
mesh.texcoords = vtData;
mesh.texcoords2 = NULL;
@@ -690,8 +705,11 @@ 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);
+#if defined(SUPPORT_FILEFORMAT_MTL)
+ if (IsFileExtension(fileName, ".mtl")) material = LoadMTL(fileName);
+#else
+ TraceLog(WARNING, "[%s] Material fileformat not supported, it can't be loaded", fileName);
+#endif
return material;
}
@@ -736,9 +754,9 @@ static Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
Color *pixels = GetImageData(heightmap);
// NOTE: One vertex per pixel
- int numTriangles = (mapX-1)*(mapZ-1)*2; // One quad every four pixels
+ int triangleCount = (mapX-1)*(mapZ-1)*2; // One quad every four pixels
- mesh.vertexCount = numTriangles*3;
+ mesh.vertexCount = triangleCount*3;
mesh.vertices = (float *)malloc(mesh.vertexCount*3*sizeof(float));
mesh.normals = (float *)malloc(mesh.vertexCount*3*sizeof(float));
@@ -1200,11 +1218,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);
+
+ Matrix matTransform = MatrixMultiply(MatrixMultiply(matScale, matRotation), matTranslation);
// 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.transform = MatrixMultiply(model.transform, matTransform);
model.material.colDiffuse = tint; // TODO: Multiply tint color by diffuse color?
rlglDrawMesh(model.mesh, model.material, model.transform);
@@ -1521,11 +1541,11 @@ RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
result.hit = true;
result.distance = t;
result.hit = true;
- result.hitNormal = VectorCrossProduct(edge1, edge2);
- VectorNormalize(&result.hitNormal);
+ result.normal = VectorCrossProduct(edge1, edge2);
+ VectorNormalize(&result.normal);
Vector3 rayDir = ray.direction;
VectorScale(&rayDir, t);
- result.hitPosition = VectorAdd(ray.position, rayDir);
+ result.position = VectorAdd(ray.position, rayDir);
}
return result;
@@ -1548,8 +1568,8 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight)
VectorScale(&rayDir, t);
result.hit = true;
result.distance = t;
- result.hitNormal = (Vector3){ 0.0, 1.0, 0.0 };
- result.hitPosition = VectorAdd(ray.position, rayDir);
+ result.normal = (Vector3){ 0.0, 1.0, 0.0 };
+ result.position = VectorAdd(ray.position, rayDir);
}
}
@@ -1588,6 +1608,7 @@ BoundingBox CalculateBoundingBox(Mesh mesh)
// Module specific Functions Definition
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_FILEFORMAT_OBJ)
// Load OBJ mesh data
static Mesh LoadOBJ(const char *fileName)
{
@@ -1596,10 +1617,10 @@ static Mesh LoadOBJ(const char *fileName)
char dataType;
char comments[200];
- int numVertex = 0;
- int numNormals = 0;
- int numTexCoords = 0;
- int numTriangles = 0;
+ int vertexCount = 0;
+ int normalCount = 0;
+ int texcoordCount = 0;
+ int triangleCount = 0;
FILE *objFile;
@@ -1611,7 +1632,7 @@ static Mesh LoadOBJ(const char *fileName)
return mesh;
}
- // First reading pass: Get numVertex, numNormals, numTexCoords, numTriangles
+ // First reading pass: Get vertexCount, normalCount, texcoordCount, triangleCount
// NOTE: vertex, texcoords and normals could be optimized (to be used indexed on faces definition)
// NOTE: faces MUST be defined as TRIANGLES (3 vertex per face)
while (!feof(objFile))
@@ -1635,40 +1656,40 @@ static Mesh LoadOBJ(const char *fileName)
if (dataType == 't') // Read texCoord
{
- numTexCoords++;
+ texcoordCount++;
fgets(comments, 200, objFile);
}
else if (dataType == 'n') // Read normals
{
- numNormals++;
+ normalCount++;
fgets(comments, 200, objFile);
}
else // Read vertex
{
- numVertex++;
+ vertexCount++;
fgets(comments, 200, objFile);
}
} break;
case 'f':
{
- numTriangles++;
+ triangleCount++;
fgets(comments, 200, objFile);
} break;
default: break;
}
}
- TraceLog(DEBUG, "[%s] Model num vertices: %i", fileName, numVertex);
- TraceLog(DEBUG, "[%s] Model num texcoords: %i", fileName, numTexCoords);
- TraceLog(DEBUG, "[%s] Model num normals: %i", fileName, numNormals);
- TraceLog(DEBUG, "[%s] Model num triangles: %i", fileName, numTriangles);
+ TraceLog(DEBUG, "[%s] Model vertices: %i", fileName, vertexCount);
+ TraceLog(DEBUG, "[%s] Model texcoords: %i", fileName, texcoordCount);
+ TraceLog(DEBUG, "[%s] Model normals: %i", fileName, normalCount);
+ TraceLog(DEBUG, "[%s] Model triangles: %i", fileName, triangleCount);
// Once we know the number of vertices to store, we create required arrays
- Vector3 *midVertices = (Vector3 *)malloc(numVertex*sizeof(Vector3));
+ Vector3 *midVertices = (Vector3 *)malloc(vertexCount*sizeof(Vector3));
Vector3 *midNormals = NULL;
- if (numNormals > 0) midNormals = (Vector3 *)malloc(numNormals*sizeof(Vector3));
+ if (normalCount > 0) midNormals = (Vector3 *)malloc(normalCount*sizeof(Vector3));
Vector2 *midTexCoords = NULL;
- if (numTexCoords > 0) midTexCoords = (Vector2 *)malloc(numTexCoords*sizeof(Vector2));
+ if (texcoordCount > 0) midTexCoords = (Vector2 *)malloc(texcoordCount*sizeof(Vector2));
int countVertex = 0;
int countNormals = 0;
@@ -1719,7 +1740,7 @@ static Mesh LoadOBJ(const char *fileName)
// At this point all vertex data (v, vt, vn) has been gathered on midVertices, midTexCoords, midNormals
// Now we can organize that data into our Mesh struct
- mesh.vertexCount = numTriangles*3;
+ mesh.vertexCount = triangleCount*3;
// Additional arrays to store vertex data as floats
mesh.vertices = (float *)malloc(mesh.vertexCount*3*sizeof(float));
@@ -1731,11 +1752,11 @@ static Mesh LoadOBJ(const char *fileName)
int tcCounter = 0; // Used to count texcoords float by float
int nCounter = 0; // Used to count normals float by float
- int vNum[3], vtNum[3], vnNum[3]; // Used to store triangle indices for v, vt, vn
+ int vCount[3], vtCount[3], vnCount[3]; // Used to store triangle indices for v, vt, vn
rewind(objFile); // Return to the beginning of the file, to read again
- if (numNormals == 0) TraceLog(INFO, "[%s] No normals data on OBJ, normals will be generated from faces data", fileName);
+ if (normalCount == 0) TraceLog(INFO, "[%s] No normals data on OBJ, normals will be generated from faces data", fileName);
// Third reading pass: Get faces (triangles) data and fill VertexArray
while (!feof(objFile))
@@ -1749,43 +1770,43 @@ static Mesh LoadOBJ(const char *fileName)
{
// NOTE: It could be that OBJ does not have normals or texcoords defined!
- 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]);
+ if ((normalCount == 0) && (texcoordCount == 0)) fscanf(objFile, "%i %i %i", &vCount[0], &vCount[1], &vCount[2]);
+ else if (normalCount == 0) fscanf(objFile, "%i/%i %i/%i %i/%i", &vCount[0], &vtCount[0], &vCount[1], &vtCount[1], &vCount[2], &vtCount[2]);
+ else if (texcoordCount == 0) fscanf(objFile, "%i//%i %i//%i %i//%i", &vCount[0], &vnCount[0], &vCount[1], &vnCount[1], &vCount[2], &vnCount[2]);
+ else fscanf(objFile, "%i/%i/%i %i/%i/%i %i/%i/%i", &vCount[0], &vtCount[0], &vnCount[0], &vCount[1], &vtCount[1], &vnCount[1], &vCount[2], &vtCount[2], &vnCount[2]);
- mesh.vertices[vCounter] = midVertices[vNum[0]-1].x;
- mesh.vertices[vCounter + 1] = midVertices[vNum[0]-1].y;
- mesh.vertices[vCounter + 2] = midVertices[vNum[0]-1].z;
+ mesh.vertices[vCounter] = midVertices[vCount[0]-1].x;
+ mesh.vertices[vCounter + 1] = midVertices[vCount[0]-1].y;
+ mesh.vertices[vCounter + 2] = midVertices[vCount[0]-1].z;
vCounter += 3;
- mesh.vertices[vCounter] = midVertices[vNum[1]-1].x;
- mesh.vertices[vCounter + 1] = midVertices[vNum[1]-1].y;
- mesh.vertices[vCounter + 2] = midVertices[vNum[1]-1].z;
+ mesh.vertices[vCounter] = midVertices[vCount[1]-1].x;
+ mesh.vertices[vCounter + 1] = midVertices[vCount[1]-1].y;
+ mesh.vertices[vCounter + 2] = midVertices[vCount[1]-1].z;
vCounter += 3;
- mesh.vertices[vCounter] = midVertices[vNum[2]-1].x;
- mesh.vertices[vCounter + 1] = midVertices[vNum[2]-1].y;
- mesh.vertices[vCounter + 2] = midVertices[vNum[2]-1].z;
+ mesh.vertices[vCounter] = midVertices[vCount[2]-1].x;
+ mesh.vertices[vCounter + 1] = midVertices[vCount[2]-1].y;
+ mesh.vertices[vCounter + 2] = midVertices[vCount[2]-1].z;
vCounter += 3;
- if (numNormals > 0)
+ if (normalCount > 0)
{
- mesh.normals[nCounter] = midNormals[vnNum[0]-1].x;
- mesh.normals[nCounter + 1] = midNormals[vnNum[0]-1].y;
- mesh.normals[nCounter + 2] = midNormals[vnNum[0]-1].z;
+ mesh.normals[nCounter] = midNormals[vnCount[0]-1].x;
+ mesh.normals[nCounter + 1] = midNormals[vnCount[0]-1].y;
+ mesh.normals[nCounter + 2] = midNormals[vnCount[0]-1].z;
nCounter += 3;
- mesh.normals[nCounter] = midNormals[vnNum[1]-1].x;
- mesh.normals[nCounter + 1] = midNormals[vnNum[1]-1].y;
- mesh.normals[nCounter + 2] = midNormals[vnNum[1]-1].z;
+ mesh.normals[nCounter] = midNormals[vnCount[1]-1].x;
+ mesh.normals[nCounter + 1] = midNormals[vnCount[1]-1].y;
+ mesh.normals[nCounter + 2] = midNormals[vnCount[1]-1].z;
nCounter += 3;
- mesh.normals[nCounter] = midNormals[vnNum[2]-1].x;
- mesh.normals[nCounter + 1] = midNormals[vnNum[2]-1].y;
- mesh.normals[nCounter + 2] = midNormals[vnNum[2]-1].z;
+ mesh.normals[nCounter] = midNormals[vnCount[2]-1].x;
+ mesh.normals[nCounter + 1] = midNormals[vnCount[2]-1].y;
+ mesh.normals[nCounter + 2] = midNormals[vnCount[2]-1].z;
nCounter += 3;
}
else
{
// If normals not defined, they are calculated from the 3 vertices [N = (V2 - V1) x (V3 - V1)]
- Vector3 norm = VectorCrossProduct(VectorSubtract(midVertices[vNum[1]-1], midVertices[vNum[0]-1]), VectorSubtract(midVertices[vNum[2]-1], midVertices[vNum[0]-1]));
+ Vector3 norm = VectorCrossProduct(VectorSubtract(midVertices[vCount[1]-1], midVertices[vCount[0]-1]), VectorSubtract(midVertices[vCount[2]-1], midVertices[vCount[0]-1]));
VectorNormalize(&norm);
mesh.normals[nCounter] = norm.x;
@@ -1802,18 +1823,18 @@ static Mesh LoadOBJ(const char *fileName)
nCounter += 3;
}
- if (numTexCoords > 0)
+ if (texcoordCount > 0)
{
// NOTE: If using negative texture coordinates with a texture filter of GL_CLAMP_TO_EDGE doesn't work!
// NOTE: Texture coordinates are Y flipped upside-down
- mesh.texcoords[tcCounter] = midTexCoords[vtNum[0]-1].x;
- mesh.texcoords[tcCounter + 1] = 1.0f - midTexCoords[vtNum[0]-1].y;
+ mesh.texcoords[tcCounter] = midTexCoords[vtCount[0]-1].x;
+ mesh.texcoords[tcCounter + 1] = 1.0f - midTexCoords[vtCount[0]-1].y;
tcCounter += 2;
- mesh.texcoords[tcCounter] = midTexCoords[vtNum[1]-1].x;
- mesh.texcoords[tcCounter + 1] = 1.0f - midTexCoords[vtNum[1]-1].y;
+ mesh.texcoords[tcCounter] = midTexCoords[vtCount[1]-1].x;
+ mesh.texcoords[tcCounter + 1] = 1.0f - midTexCoords[vtCount[1]-1].y;
tcCounter += 2;
- mesh.texcoords[tcCounter] = midTexCoords[vtNum[2]-1].x;
- mesh.texcoords[tcCounter + 1] = 1.0f - midTexCoords[vtNum[2]-1].y;
+ mesh.texcoords[tcCounter] = midTexCoords[vtCount[2]-1].x;
+ mesh.texcoords[tcCounter + 1] = 1.0f - midTexCoords[vtCount[2]-1].y;
tcCounter += 2;
}
} break;
@@ -1824,7 +1845,77 @@ static Mesh LoadOBJ(const char *fileName)
fclose(objFile);
// Security check, just in case no normals or no texcoords defined in OBJ
- if (numTexCoords == 0) for (int i = 0; i < (2*mesh.vertexCount); i++) mesh.texcoords[i] = 0.0f;
+ if (texcoordCount == 0) for (int i = 0; i < (2*mesh.vertexCount); i++) mesh.texcoords[i] = 0.0f;
+ else
+ {
+ // Attempt to calculate mesh tangents and binormals using positions and texture coordinates
+ mesh.tangents = (float *)malloc(mesh.vertexCount*3*sizeof(float));
+ // mesh.binormals = (float *)malloc(mesh.vertexCount*3*sizeof(float));
+
+ int vCount = 0;
+ int uvCount = 0;
+ while (vCount < mesh.vertexCount*3)
+ {
+ // Calculate mesh vertex positions as Vector3
+ Vector3 v0 = { mesh.vertices[vCount], mesh.vertices[vCount + 1], mesh.vertices[vCount + 2] };
+ Vector3 v1 = { mesh.vertices[vCount + 3], mesh.vertices[vCount + 4], mesh.vertices[vCount + 5] };
+ Vector3 v2 = { mesh.vertices[vCount + 6], mesh.vertices[vCount + 7], mesh.vertices[vCount + 8] };
+
+ // Calculate mesh texture coordinates as Vector2
+ Vector2 uv0 = { mesh.texcoords[uvCount + 0], mesh.texcoords[uvCount + 1] };
+ Vector2 uv1 = { mesh.texcoords[uvCount + 2], mesh.texcoords[uvCount + 3] };
+ Vector2 uv2 = { mesh.texcoords[uvCount + 4], mesh.texcoords[uvCount + 5] };
+
+ // Calculate edges of the triangle (position delta)
+ Vector3 deltaPos1 = VectorSubtract(v1, v0);
+ Vector3 deltaPos2 = VectorSubtract(v2, v0);
+
+ // UV delta
+ Vector2 deltaUV1 = { uv1.x - uv0.x, uv1.y - uv0.y };
+ Vector2 deltaUV2 = { uv2.x - uv0.x, uv2.y - uv0.y };
+
+ float r = 1.0f/(deltaUV1.x*deltaUV2.y - deltaUV1.y*deltaUV2.x);
+ Vector3 t1 = { deltaPos1.x*deltaUV2.y, deltaPos1.y*deltaUV2.y, deltaPos1.z*deltaUV2.y };
+ Vector3 t2 = { deltaPos2.x*deltaUV1.y, deltaPos2.y*deltaUV1.y, deltaPos2.z*deltaUV1.y };
+ // Vector3 b1 = { deltaPos2.x*deltaUV1.x, deltaPos2.y*deltaUV1.x, deltaPos2.z*deltaUV1.x };
+ // Vector3 b2 = { deltaPos1.x*deltaUV2.x, deltaPos1.y*deltaUV2.x, deltaPos1.z*deltaUV2.x };
+
+ // Calculate vertex tangent
+ Vector3 tangent = VectorSubtract(t1, t2);
+ VectorScale(&tangent, r);
+
+ // Apply calculated tangents data to mesh struct
+ mesh.tangents[vCount + 0] = tangent.x;
+ mesh.tangents[vCount + 1] = tangent.y;
+ mesh.tangents[vCount + 2] = tangent.z;
+ mesh.tangents[vCount + 3] = tangent.x;
+ mesh.tangents[vCount + 4] = tangent.y;
+ mesh.tangents[vCount + 5] = tangent.z;
+ mesh.tangents[vCount + 6] = tangent.x;
+ mesh.tangents[vCount + 7] = tangent.y;
+ mesh.tangents[vCount + 8] = tangent.z;
+
+ // TODO: add binormals to mesh struct and assign buffers id and locations properly
+ /* // Calculate vertex binormal
+ Vector3 binormal = VectorSubtract(b1, b2);
+ VectorScale(&binormal, r);
+
+ // Apply calculated binormals data to mesh struct
+ mesh.binormals[vCount + 0] = binormal.x;
+ mesh.binormals[vCount + 1] = binormal.y;
+ mesh.binormals[vCount + 2] = binormal.z;
+ mesh.binormals[vCount + 3] = binormal.x;
+ mesh.binormals[vCount + 4] = binormal.y;
+ mesh.binormals[vCount + 5] = binormal.z;
+ mesh.binormals[vCount + 6] = binormal.x;
+ mesh.binormals[vCount + 7] = binormal.y;
+ mesh.binormals[vCount + 8] = binormal.z; */
+
+ // Update vertex position and texture coordinates counters
+ vCount += 9;
+ uvCount += 6;
+ }
+ }
// Now we can free temp mid* arrays
free(midVertices);
@@ -1836,7 +1927,9 @@ static Mesh LoadOBJ(const char *fileName)
return mesh;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_MTL)
// Load MTL material data (specs: http://paulbourke.net/dataformats/mtl/)
// NOTE: Texture map parameters are not supported
static Material LoadMTL(const char *fileName)
@@ -2000,3 +2093,4 @@ static Material LoadMTL(const char *fileName)
return material;
}
+#endif
diff --git a/src/physac.h b/src/physac.h
index cb0e3f3c..d3fdaca4 100644
--- a/src/physac.h
+++ b/src/physac.h
@@ -2,22 +2,22 @@
*
* Physac v1.0 - 2D Physics library for videogames
*
-* DESCRIPTION:
+* DESCRIPTION:
*
-* Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop
-* to simluate physics. A physics step contains the following phases: get collision information,
-* apply dynamics, collision solving and position correction. It uses a very simple struct for physic
+* Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop
+* to simluate physics. A physics step contains the following phases: get collision information,
+* apply dynamics, collision solving and position correction. It uses a very simple struct for physic
* bodies with a position vector to be used in any 3D rendering API.
-*
+*
* CONFIGURATION:
-*
+*
* #define PHYSAC_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
+* 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 PHYSAC_STATIC (defined by default)
-* The generated implementation will stay private inside implementation file and all
+* The generated implementation will stay private inside implementation file and all
* internal symbols and functions will only be visible inside that file.
*
* #define PHYSAC_NO_THREADS
@@ -30,7 +30,7 @@
* the user (check library implementation for further details).
*
* #define PHYSAC_DEBUG
-* Traces log messages when creating and destroying physics bodies and detects errors in physics
+* Traces log messages when creating and destroying physics bodies and detects errors in physics
* calculations and reference exceptions; it is useful for debug purposes
*
* #define PHYSAC_MALLOC()
@@ -38,13 +38,21 @@
* 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.
*
+*
+* NOTE 1: Physac requires multi-threading, when InitPhysics() a second thread is created to manage physics calculations.
+* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread)
+*
+* Use the following code to compile:
+* gcc -o physac_sample.exe physac_sample.c -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread \
+* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition
+*
* VERY THANKS TO:
* Ramón Santamaria (@raysan5)
*
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2016 Victor Fisac
+* Copyright (c) 2016-2017 Victor Fisac
*
* 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.
@@ -66,7 +74,7 @@
#if !defined(PHYSAC_H)
#define PHYSAC_H
-#define PHYSAC_STATIC
+// #define PHYSAC_STATIC
// #define PHYSAC_NO_THREADS
// #define PHYSAC_STANDALONE
// #define PHYSAC_DEBUG
@@ -238,11 +246,14 @@ PHYSACDEF void ClosePhysics(void);
#include <stdlib.h> // Required for: malloc(), free(), srand(), rand()
#include <math.h> // Required for: cosf(), sinf(), fabs(), sqrtf()
+#include "raymath.h" // Required for: Vector2Add(), Vector2Subtract()
+
#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) || defined(PLATFORM_WEB)
+#elif defined(__linux__) || defined(PLATFORM_WEB)
+ //#define _DEFAULT_SOURCE // Enables BSD function definitions and C99 POSIX compliance
#include <sys/time.h> // Required for: timespec
#include <time.h> // Required for: clock_gettime()
#include <stdint.h>
@@ -265,13 +276,13 @@ PHYSACDEF void ClosePhysics(void);
// Global Variables Definition
//----------------------------------------------------------------------------------
#if !defined(PHYSAC_NO_THREADS)
- static pthread_t physicsThreadId; // Physics thread id
+static pthread_t physicsThreadId; // Physics thread id
#endif
static unsigned int usedMemory = 0; // Total allocated dynamic memory
static bool physicsThreadEnabled = false; // Physics thread enabled state
static double currentTime = 0; // Current time in milliseconds
-#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux) || defined(PLATFORM_WEB)
- static double baseTime = 0; // Android and RPI platforms base time
+#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux__) || defined(PLATFORM_WEB)
+static double baseTime = 0; // Android and RPI platforms base time
#endif
static double startTime = 0; // Start time in milliseconds
static double deltaTime = 0; // Delta time used for physics steps
@@ -307,10 +318,12 @@ static void FindIncidentFace(Vector2 *v0, Vector2 *v1, PhysicsShape ref, Physics
static int Clip(Vector2 normal, float clip, Vector2 *faceA, Vector2 *faceB); // Calculates clipping based on a normal and two faces
static bool BiasGreaterThan(float valueA, float valueB); // Check if values are between bias range
static Vector2 TriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3); // Returns the barycenter of a triangle given by 3 points
+
static void InitTimer(void); // Initializes hi-resolution timer
static double GetCurrentTime(void); // Get current time in milliseconds
static int GetRandomNumber(int min, int max); // Returns a random number between min and max (both included)
+// Math functions
static void MathClamp(double *value, double min, double max); // Clamp a value in a range
static Vector2 MathCross(float value, Vector2 vector); // Returns the cross product of a vector and a value
static float MathCrossVector2(Vector2 v1, Vector2 v2); // Returns the cross product of two vectors
@@ -318,8 +331,10 @@ static float MathLenSqr(Vector2 vector);
static float MathDot(Vector2 v1, Vector2 v2); // Returns the dot product of two vectors
static inline float DistSqr(Vector2 v1, Vector2 v2); // Returns the square root of distance between two vectors
static void MathNormalize(Vector2 *vector); // Returns the normalized values of a vector
+#if defined(PHYSAC_STANDALONE)
static Vector2 Vector2Add(Vector2 v1, Vector2 v2); // Returns the sum of two given vectors
static Vector2 Vector2Subtract(Vector2 v1, Vector2 v2); // Returns the subtract of two given vectors
+#endif
static Mat2 Mat2Radians(float radians); // Creates a matrix 2x2 from a given radians value
static void Mat2Set(Mat2 *matrix, float radians); // Set values from radians to a created matrix 2x2
@@ -361,70 +376,6 @@ PHYSACDEF PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float d
{
PhysicsBody newBody = CreatePhysicsBodyPolygon(pos, radius, PHYSAC_CIRCLE_VERTICES, density);
return newBody;
-
- /*PhysicsBody newBody = (PhysicsBody)PHYSAC_MALLOC(sizeof(PhysicsBodyData));
- usedMemory += sizeof(PhysicsBodyData);
-
- int newId = -1;
- for (int i = 0; i < PHYSAC_MAX_BODIES; i++)
- {
- int currentId = i;
-
- // Check if current id already exist in other physics body
- for (int k = 0; k < physicsBodiesCount; k++)
- {
- if (bodies[k]->id == currentId)
- {
- currentId++;
- break;
- }
- }
-
- // If it is not used, use it as new physics body id
- if (currentId == i)
- {
- newId = i;
- break;
- }
- }
-
- if (newId != -1)
- {
- // Initialize new body with generic values
- newBody->id = newId;
- newBody->enabled = true;
- newBody->position = pos;
- newBody->velocity = (Vector2){ 0 };
- newBody->force = (Vector2){ 0 };
- newBody->angularVelocity = 0;
- newBody->torque = 0;
- newBody->orient = 0;
- newBody->mass = PHYSAC_PI*radius*radius*density;
- newBody->inverseMass = ((newBody->mass != 0.0f) ? 1.0f/newBody->mass : 0.0f);
- newBody->inertia = newBody->mass*radius*radius;
- newBody->inverseInertia = ((newBody->inertia != 0.0f) ? 1.0f/newBody->inertia : 0.0f);
- newBody->staticFriction = 0;
- newBody->dynamicFriction = 0;
- newBody->restitution = 0;
- newBody->useGravity = true;
- newBody->freezeOrient = false;
- newBody->shape.type = PHYSICS_CIRCLE;
- newBody->shape.body = newBody;
- newBody->shape.radius = radius;
-
- // Add new body to bodies pointers array and update bodies count
- bodies[physicsBodiesCount] = newBody;
- physicsBodiesCount++;
-
- #if defined(PHYSAC_DEBUG)
- printf("[PHYSAC] created circle physics body id %i\n", newBody->id);
- #endif
- }
- #if defined(PHYSAC_DEBUG)
- else printf("[PHYSAC] new physics body creation failed because there is any available id to use\n");
- #endif
-
- return newBody;*/
}
// Creates a new rectangle physics body with generic parameters
@@ -461,7 +412,7 @@ PHYSACDEF PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float
// Initialize new body with generic values
newBody->id = newId;
newBody->enabled = true;
- newBody->position = pos;
+ newBody->position = pos;
newBody->velocity = (Vector2){ 0 };
newBody->force = (Vector2){ 0 };
newBody->angularVelocity = 0;
@@ -569,7 +520,7 @@ PHYSACDEF PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int si
// Initialize new body with generic values
newBody->id = newId;
newBody->enabled = true;
- newBody->position = pos;
+ newBody->position = pos;
newBody->velocity = (Vector2){ 0 };
newBody->force = (Vector2){ 0 };
newBody->angularVelocity = 0;
@@ -802,82 +753,74 @@ PHYSACDEF int GetPhysicsBodiesCount(void)
// Returns a physics body of the bodies pool at a specific index
PHYSACDEF PhysicsBody GetPhysicsBody(int index)
{
+ PhysicsBody body = NULL;
+
if (index < physicsBodiesCount)
{
- PhysicsBody body = bodies[index];
- if (body != NULL) return body;
- else
+ body = bodies[index];
+
+ if (body == NULL)
{
#if defined(PHYSAC_DEBUG)
printf("[PHYSAC] error when trying to get a null reference physics body");
#endif
-
- return NULL;
}
}
#if defined(PHYSAC_DEBUG)
- else
- {
- printf("[PHYSAC] physics body index is out of bounds");
- return NULL;
- }
+ else printf("[PHYSAC] physics body index is out of bounds");
#endif
+
+ return body;
}
// Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
PHYSACDEF int GetPhysicsShapeType(int index)
{
+ int result = -1;
+
if (index < physicsBodiesCount)
{
PhysicsBody body = bodies[index];
- if (body != NULL) return body->shape.type;
+
+ if (body != NULL) result = body->shape.type;
#if defined(PHYSAC_DEBUG)
- else
- {
- printf("[PHYSAC] error when trying to get a null reference physics body");
- return -1;
- }
+ else printf("[PHYSAC] error when trying to get a null reference physics body");
#endif
}
#if defined(PHYSAC_DEBUG)
- else
- {
- printf("[PHYSAC] physics body index is out of bounds");
- return -1;
- }
+ else printf("[PHYSAC] physics body index is out of bounds");
#endif
+
+ return result;
}
// Returns the amount of vertices of a physics body shape
PHYSACDEF int GetPhysicsShapeVerticesCount(int index)
{
+ int result = 0;
+
if (index < physicsBodiesCount)
{
PhysicsBody body = bodies[index];
+
if (body != NULL)
{
switch (body->shape.type)
{
- case PHYSICS_CIRCLE: return PHYSAC_CIRCLE_VERTICES; break;
- case PHYSICS_POLYGON: return body->shape.vertexData.vertexCount; break;
+ case PHYSICS_CIRCLE: result = PHYSAC_CIRCLE_VERTICES; break;
+ case PHYSICS_POLYGON: result = body->shape.vertexData.vertexCount; break;
default: break;
}
}
#if defined(PHYSAC_DEBUG)
- else
- {
- printf("[PHYSAC] error when trying to get a null reference physics body");
- return 0;
- }
+ else printf("[PHYSAC] error when trying to get a null reference physics body");
#endif
}
#if defined(PHYSAC_DEBUG)
- else
- {
- printf("[PHYSAC] physics body index is out of bounds");
- return 0;
- }
+ else printf("[PHYSAC] physics body index is out of bounds");
#endif
+
+ return result;
}
// Returns transformed position of a body shape (body position + vertex transformed position)
@@ -1130,6 +1073,7 @@ static void *PhysicsLoop(void *arg)
// Physics steps calculations (dynamics, collisions and position corrections)
static void PhysicsStep(void)
{
+ // Update current steps count
stepsCount++;
// Clear previous generated collisions information
@@ -1139,6 +1083,13 @@ static void PhysicsStep(void)
if (manifold != NULL) DestroyPhysicsManifold(manifold);
}
+ // Reset physics bodies grounded state
+ for (int i = 0; i < physicsBodiesCount; i++)
+ {
+ PhysicsBody body = bodies[i];
+ body->isGrounded = false;
+ }
+
// Generate new collision information
for (int i = 0; i < physicsBodiesCount; i++)
{
@@ -1257,7 +1208,7 @@ static PhysicsManifold CreatePhysicsManifold(PhysicsBody a, PhysicsBody b)
}
if (newId != -1)
- {
+ {
// Initialize new manifold with generic values
newManifold->id = newId;
newManifold->bodyA = a;
@@ -1348,8 +1299,8 @@ static void SolvePhysicsManifold(PhysicsManifold manifold)
default: break;
}
- // Update physics body grounded state if normal direction is downside
- manifold->bodyB->isGrounded = (manifold->normal.y < 0);
+ // Update physics body grounded state if normal direction is down and grounded state is not set yet in previous manifolds
+ if (!manifold->bodyB->isGrounded) manifold->bodyB->isGrounded = (manifold->normal.y < 0);
}
// Solves collision between two circle shape physics bodies
@@ -1388,7 +1339,7 @@ static void SolveCircleToCircle(PhysicsManifold manifold)
}
// Update physics body grounded state if normal direction is down
- if (manifold->normal.y < 0) bodyA->isGrounded = true;
+ if (!bodyA->isGrounded) bodyA->isGrounded = (manifold->normal.y < 0);
}
// Solves collision between a circle to a polygon shape physics bodies
@@ -1444,7 +1395,7 @@ static void SolveCircleToPolygon(PhysicsManifold manifold)
manifold->penetration = bodyA->shape.radius - separation;
if (dot1 <= 0) // Closest to v1
- {
+ {
if (DistSqr(center, v1) > bodyA->shape.radius*bodyA->shape.radius) return;
manifold->contactsCount = 1;
@@ -1649,7 +1600,7 @@ static void IntegratePhysicsImpulses(PhysicsManifold manifold)
// Early out and positional correct if both objects have infinite mass
if (fabs(bodyA->inverseMass + bodyB->inverseMass) <= PHYSAC_EPSILON)
{
- bodyA->velocity = (Vector2){ 0 };
+ bodyA->velocity = (Vector2){ 0 };
bodyB->velocity = (Vector2){ 0 };
return;
}
@@ -1678,7 +1629,7 @@ static void IntegratePhysicsImpulses(PhysicsManifold manifold)
// Calculate impulse scalar value
float impulse = -(1.0f + manifold->restitution)*contactVelocity;
- impulse /= inverseMassSum;
+ impulse /= inverseMassSum;
impulse /= (float)manifold->contactsCount;
// Apply impulse to each physics body
@@ -1955,7 +1906,7 @@ static double GetCurrentTime(void)
time = (double)((double)currentTime/clockFrequency)*1000;
#endif
- #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux) || defined(PLATFORM_WEB)
+ #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux__) || defined(PLATFORM_WEB)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
@@ -2033,6 +1984,7 @@ static void MathNormalize(Vector2 *vector)
vector->y *= ilength;
}
+#if defined(PHYSAC_STANDALONE)
// Returns the sum of two given vectors
static inline Vector2 Vector2Add(Vector2 v1, Vector2 v2)
{
@@ -2043,7 +1995,7 @@ static inline Vector2 Vector2Add(Vector2 v1, Vector2 v2)
static inline Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
{
return (Vector2){ v1.x - v2.x, v1.y - v2.y };
-}
+#endif
// Creates a matrix 2x2 from a given radians value
static inline Mat2 Mat2Radians(float radians)
diff --git a/src/raylib.h b/src/raylib.h
index beda833c..0b1a6b19 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1,43 +1,43 @@
/**********************************************************************************************
*
-* raylib v1.7.0 (www.raylib.com)
+* raylib v1.7.0
*
-* A simple and easy-to-use library to learn videogames programming
+* A simple and easy-to-use library to learn videogames programming (www.raylib.com)
*
* FEATURES:
-* Library written in plain C code (C99)
-* Uses 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
-* Powerful math module for Vector, Matrix and Quaternion operations: [raymath]
-* Audio loading and playing with streaming support and mixing channels [audio]
-* VR stereo rendering support with configurable HMD device parameters
-* 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)
-* Complete binding for Lua [rlua]
+* - Library written in plain C code (C99)
+* - Multiple platforms supported: Windows, Linux, Mac, Android, Raspberry Pi, HTML5.
+* - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES 2.0)
+* - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
+* - Powerful fonts module with SpriteFonts support (XNA bitmap fonts, AngelCode fonts, TTF)
+* - Multiple textures support, including compressed formats and mipmaps generation
+* - Basic 3d support for Shapes, Models, Billboards, Heightmaps and Cubicmaps
+* - Powerful math module for Vector2, Vector3, Matrix and Quaternion operations: [raymath]
+* - Audio loading and playing with streaming support and mixing channels: [audio]
+* - VR stereo rendering support with configurable HMD device parameters
+* - Minimal external dependencies (GLFW3, OpenGL, OpenAL)
+* - Complete bindings for Lua, Go and Pascal
*
* NOTES:
-* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte)
-* One custom default font could be loaded automatically when InitWindow() [core]
-* 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 could be loaded automatically (internally defined)
+* 32bit Colors - Any defined Color is always RGBA (4 byte)
+* One custom font is loaded by default when InitWindow() [core]
+* If using OpenGL 3.3 or ES2, one default shader is loaded automatically (internally defined) [rlgl]
+* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads
*
* DEPENDENCIES:
-* GLFW3 (www.glfw.org) for window/context management and input [core]
-* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl]
-* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA) [textures]
-* stb_image_write (Sean Barret) for image writting (PNG) [utils]
-* stb_truetype (Sean Barret) for ttf fonts loading [text]
-* stb_vorbis (Sean Barret) for ogg audio loading [audio]
-* jar_xm (Joshua Reisenauer) for XM audio module loading [audio]
-* jar_mod (Joshua Reisenauer) for MOD audio module loading [audio]
-* dr_flac (David Reid) for FLAC audio file loading [audio]
-* OpenAL Soft for audio device/context management [audio]
-* tinfl for data decompression (DEFLATE algorithm) [utils]
+* GLFW3 (www.glfw.org) for window/context management and input [core]
+* GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl]
+* OpenAL Soft for audio device/context management [audio]
+*
+* OPTIONAL DEPENDENCIES:
+* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA) [textures]
+* stb_image_write (Sean Barret) for image writting (PNG) [utils]
+* stb_truetype (Sean Barret) for ttf fonts loading [text]
+* stb_vorbis (Sean Barret) for ogg audio loading [audio]
+* jar_xm (Joshua Reisenauer) for XM audio module loading [audio]
+* jar_mod (Joshua Reisenauer) for MOD audio module loading [audio]
+* dr_flac (David Reid) for FLAC audio file loading [audio]
+* tinfl for data decompression (DEFLATE algorithm) [rres]
*
*
* LICENSE: zlib/libpng
@@ -45,7 +45,7 @@
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software:
*
-* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2013-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -72,7 +72,6 @@
//#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)
@@ -98,13 +97,13 @@
#define RAD2DEG (180.0f/PI)
// raylib Config Flags
-#define FLAG_SHOW_LOGO 1 // Set this flag to show raylib logo at startup
-#define FLAG_FULLSCREEN_MODE 2 // Set this flag to run program in fullscreen
-#define FLAG_WINDOW_RESIZABLE 4 // Set this flag to allow resizable window
-#define FLAG_WINDOW_DECORATED 8 // Set this flag to show window decoration (frame and buttons)
-#define FLAG_WINDOW_TRANSPARENT 16 // Set this flag to allow transparent window
-#define FLAG_MSAA_4X_HINT 32 // Set this flag to try enabling MSAA 4X
-#define FLAG_VSYNC_HINT 64 // Set this flag to try enabling V-Sync on GPU
+#define FLAG_SHOW_LOGO 1 // Set to show raylib logo at startup
+#define FLAG_FULLSCREEN_MODE 2 // Set to run program in fullscreen
+#define FLAG_WINDOW_RESIZABLE 4 // Set to allow resizable window
+#define FLAG_WINDOW_DECORATED 8 // Set to show window decoration (frame and buttons)
+#define FLAG_WINDOW_TRANSPARENT 16 // Set to allow transparent window
+#define FLAG_MSAA_4X_HINT 32 // Set to try enabling MSAA 4X
+#define FLAG_VSYNC_HINT 64 // Set to try enabling V-Sync on GPU
// Keyboard Function Keys
#define KEY_SPACE 32
@@ -293,7 +292,7 @@
#define RAYWHITE CLITERAL{ 245, 245, 245, 255 } // My own White (raylib logo)
//----------------------------------------------------------------------------------
-// Types and Structures Definition
+// Structures Definition
//----------------------------------------------------------------------------------
#ifndef __cplusplus
// Boolean type
@@ -350,7 +349,7 @@ typedef struct Image {
int format; // Data format (TextureFormat type)
} Image;
-// Texture2D type, bpp always RGBA (32bit)
+// Texture2D type
// NOTE: Data stored in GPU memory
typedef struct Texture2D {
unsigned int id; // OpenGL texture id
@@ -474,12 +473,12 @@ typedef struct Ray {
Vector3 direction; // Ray direction
} Ray;
-// Information returned from a raycast
+// Raycast hit information
typedef struct RayHitInfo {
bool hit; // Did the ray hit something?
float distance; // Distance to nearest hit
- Vector3 hitPosition; // Position of nearest hit
- Vector3 hitNormal; // Surface normal of hit
+ Vector3 position; // Position of nearest hit
+ Vector3 normal; // Surface normal of hit
} RayHitInfo;
// Wave type, defines audio wave data
@@ -514,6 +513,34 @@ typedef struct AudioStream {
unsigned int buffers[2]; // OpenAL audio buffers (double buffering)
} AudioStream;
+// rRES data returned when reading a resource,
+// it contains all required data for user (24 byte)
+typedef struct RRESData {
+ unsigned int type; // Resource type (4 byte)
+
+ unsigned int param1; // Resouce parameter 1 (4 byte)
+ unsigned int param2; // Resouce parameter 2 (4 byte)
+ unsigned int param3; // Resouce parameter 3 (4 byte)
+ unsigned int param4; // Resouce parameter 4 (4 byte)
+
+ void *data; // Resource data pointer (4 byte)
+} RRESData;
+
+// RRES type (pointer to RRESData array)
+typedef struct RRESData *RRES;
+
+//----------------------------------------------------------------------------------
+// Enumerators Definition
+//----------------------------------------------------------------------------------
+// Trace log type
+typedef enum {
+ INFO = 0,
+ WARNING,
+ ERROR,
+ DEBUG,
+ OTHER
+} LogType;
+
// Texture formats
// NOTE: Support depends on OpenGL version and platform
typedef enum {
@@ -524,6 +551,7 @@ typedef enum {
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
UNCOMPRESSED_R8G8B8A8, // 32 bpp
+ UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
COMPRESSED_DXT3_RGBA, // 8 bpp
@@ -550,10 +578,18 @@ typedef enum {
} TextureFilterMode;
// Texture parameters: wrap mode
-typedef enum { WRAP_REPEAT = 0, WRAP_CLAMP, WRAP_MIRROR } TextureWrapMode;
+typedef enum {
+ WRAP_REPEAT = 0,
+ WRAP_CLAMP,
+ WRAP_MIRROR
+} TextureWrapMode;
// Color blending modes (pre-defined)
-typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
+typedef enum {
+ BLEND_ALPHA = 0,
+ BLEND_ADDITIVE,
+ BLEND_MULTIPLIED
+} BlendMode;
// Gestures type
// NOTE: It could be used as flags to enable only some gestures
@@ -593,19 +629,6 @@ typedef enum {
HMD_FOVE_VR,
} VrDevice;
-// rRES data returned when reading a resource,
-// it contains all required data for user (24 byte)
-typedef struct RRESData {
- unsigned int type; // Resource type (4 byte)
-
- unsigned int param1; // Resouce parameter 1 (4 byte)
- unsigned int param2; // Resouce parameter 2 (4 byte)
- unsigned int param3; // Resouce parameter 3 (4 byte)
- unsigned int param4; // Resouce parameter 4 (4 byte)
-
- void *data; // Resource data pointer (4 byte)
-} RRESData;
-
// RRESData type
typedef enum {
RRES_TYPE_RAW = 0,
@@ -618,9 +641,6 @@ typedef enum {
RRES_TYPE_DIRECTORY
} RRESDataType;
-// RRES type (pointer to RRESData array)
-typedef struct RRESData *RRES;
-
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
@@ -633,71 +653,88 @@ extern "C" { // Prevents name mangling of functions
//------------------------------------------------------------------------------------
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
+
+// Window-related functions
#if defined(PLATFORM_ANDROID)
-RLAPI void InitWindow(int width, int height, void *state); // Init Android Activity and OpenGL Graphics (struct android_app)
+RLAPI void InitWindow(int width, int height, void *state); // Initialize Android activity
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
-RLAPI void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
+RLAPI void InitWindow(int width, int height, const char *title); // Initialize window and OpenGL context
#endif
-
-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 void CloseWindow(void); // Close window and unload OpenGL context
+RLAPI bool WindowShouldClose(void); // Check if KEY_ESCAPE pressed or Close icon pressed
+RLAPI bool IsWindowMinimized(void); // Check if window has been minimized (or lost focus)
+RLAPI void ToggleFullscreen(void); // Toggle fullscreen mode (only PLATFORM_DESKTOP)
RLAPI void SetWindowIcon(Image image); // Set icon for window (only PLATFORM_DESKTOP)
RLAPI void SetWindowPosition(int x, int y); // Set window position on screen (only PLATFORM_DESKTOP)
RLAPI void SetWindowMonitor(int monitor); // Set monitor for the current window (fullscreen mode)
+RLAPI void SetWindowMinSize(int width, int height); // Set window minimum dimensions (for FLAG_WINDOW_RESIZABLE)
RLAPI int GetScreenWidth(void); // Get current screen width
RLAPI int GetScreenHeight(void); // Get current screen height
#if !defined(PLATFORM_ANDROID)
+// Cursor-related functions
RLAPI void ShowCursor(void); // Shows cursor
RLAPI void HideCursor(void); // Hides cursor
-RLAPI bool IsCursorHidden(void); // Returns true if cursor is not visible
-RLAPI void EnableCursor(void); // Enables cursor
-RLAPI void DisableCursor(void); // Disables cursor
+RLAPI bool IsCursorHidden(void); // Check if cursor is not visible
+RLAPI void EnableCursor(void); // Enables cursor (unlock cursor)
+RLAPI void DisableCursor(void); // Disables cursor (lock cursor)
#endif
-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)
+// Drawing-related functions
+RLAPI void ClearBackground(Color color); // Set background color (framebuffer clear color)
+RLAPI void BeginDrawing(void); // Setup canvas (framebuffer) to start drawing
+RLAPI void EndDrawing(void); // End canvas drawing and swap buffers (double buffering)
+RLAPI void Begin2dMode(Camera2D camera); // Initialize 2D mode with custom camera (2D)
+RLAPI void End2dMode(void); // Ends 2D mode with custom camera
+RLAPI void Begin3dMode(Camera camera); // Initializes 3D mode with custom camera (3D)
RLAPI void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
RLAPI void BeginTextureMode(RenderTexture2D target); // Initializes render texture for drawing
RLAPI void EndTextureMode(void); // Ends drawing to render texture
+// Screen-space-related functions
RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a ray trace from mouse position
-RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position from a 3d world space position
+RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position
RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix)
+// Timming-related functions
RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum)
RLAPI int GetFPS(void); // Returns current FPS
-RLAPI float GetFrameTime(void); // Returns time in seconds for one frame
+RLAPI float GetFrameTime(void); // Returns time in seconds for last frame drawn
-RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+// Color-related functions
RLAPI int GetHexValue(Color color); // Returns hexadecimal value for a Color
+RLAPI Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
+RLAPI Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
RLAPI float *ColorToFloat(Color color); // Converts Color to float array and normalizes
RLAPI float *VectorToFloat(Vector3 vec); // Converts Vector3 to float array
RLAPI float *MatrixToFloat(Matrix mat); // Converts Matrix to float array
+// Misc. functions
+RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags)
+RLAPI void SetConfigFlags(char flags); // Setup window configuration flags (view FLAGS)
+RLAPI void TraceLog(int logType, const char *text, ...); // Show trace log messages (INFO, WARNING, ERROR, DEBUG)
+RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (saved a .png)
RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
-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
+// Files management functions
+RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension
+RLAPI const char *GetDirectoryPath(const char *fileName); // Get directory for a given fileName (with path)
+RLAPI const char *GetWorkingDirectory(void); // Get current working directory
+RLAPI bool ChangeDirectory(const char *dir); // Change working directory, returns true if success
+RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
+RLAPI char **GetDroppedFiles(int *count); // Get dropped files names
RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer
-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)
+// Persistent storage management
+RLAPI void StorageSaveValue(int position, int value); // Save integer value to storage file (to defined position)
+RLAPI int StorageLoadValue(int position); // Load integer value from storage file (from defined position)
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
//------------------------------------------------------------------------------------
+
+// Input-related functions: keyboard
RLAPI bool IsKeyPressed(int key); // Detect if a key has been pressed once
RLAPI bool IsKeyDown(int key); // Detect if a key is being pressed
RLAPI bool IsKeyReleased(int key); // Detect if a key has been released once
@@ -705,6 +742,7 @@ RLAPI bool IsKeyUp(int key); // Detect if a key
RLAPI int GetKeyPressed(void); // Get latest key pressed
RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
+// Input-related functions: gamepads
RLAPI bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
RLAPI bool IsGamepadName(int gamepad, const char *name); // Check gamepad name (if available)
RLAPI const char *GetGamepadName(int gamepad); // Return gamepad internal name id
@@ -716,6 +754,7 @@ RLAPI int GetGamepadButtonPressed(void); // Get the last ga
RLAPI int GetGamepadAxisCount(int gamepad); // Return gamepad axis count for a gamepad
RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Return axis movement value for a gamepad axis
+// Input-related functions: mouse
RLAPI bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
RLAPI bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
RLAPI bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
@@ -726,6 +765,7 @@ RLAPI Vector2 GetMousePosition(void); // Returns mouse p
RLAPI void SetMousePosition(Vector2 position); // Set mouse position XY
RLAPI int GetMouseWheelMove(void); // Returns mouse wheel movement Y
+// Input-related functions: touch
RLAPI int GetTouchX(void); // Returns touch position X for touch point 0 (relative to screen size)
RLAPI int GetTouchY(void); // Returns touch position Y for touch point 0 (relative to screen size)
RLAPI Vector2 GetTouchPosition(int index); // Returns touch position XY for a touch point index (relative to screen size)
@@ -759,10 +799,14 @@ RLAPI void SetCameraMoveControls(int frontKey, int backKey,
//------------------------------------------------------------------------------------
// Basic Shapes Drawing Functions (Module: shapes)
//------------------------------------------------------------------------------------
+
+// Basic shapes drawing functions
RLAPI void DrawPixel(int posX, int posY, Color color); // Draw a pixel
RLAPI void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
RLAPI void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
RLAPI void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
+RLAPI void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line defining thickness
+RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw a line using cubic-bezier curves in-out
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
@@ -779,6 +823,7 @@ RLAPI void DrawPoly(Vector2 center, int sides, float radius, float rotation, Col
RLAPI void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
RLAPI void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
+// Basic shapes collision detection functions
RLAPI bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
RLAPI bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
RLAPI bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
@@ -790,6 +835,8 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve
//------------------------------------------------------------------------------------
// Texture Loading and Drawing Functions (Module: textures)
//------------------------------------------------------------------------------------
+
+// Image/Texture2D data loading/unloading functions
RLAPI Image LoadImage(const char *fileName); // Load image from file into CPU memory (RAM)
RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image from Color array data (RGBA - 32bit)
RLAPI Image LoadImagePro(void *data, int width, int height, int format); // Load image from raw data with parameters
@@ -803,6 +850,8 @@ RLAPI void UnloadRenderTexture(RenderTexture2D target);
RLAPI Color *GetImageData(Image image); // Get pixel data from image as a Color struct array
RLAPI Image GetTextureData(Texture2D texture); // Get pixel data from GPU texture and return an Image
RLAPI void UpdateTexture(Texture2D texture, const void *pixels); // Update GPU texture with new data
+
+// Image manipulation functions
RLAPI void ImageToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
RLAPI void ImageFormat(Image *image, int newFormat); // Convert image data to desired format
RLAPI void ImageAlphaMask(Image *image, Image alphaMask); // Apply alpha mask to image
@@ -824,10 +873,13 @@ RLAPI void ImageColorInvert(Image *image);
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)
+
+// Texture2D configuration functions
RLAPI void GenTextureMipmaps(Texture2D *texture); // Generate GPU mipmaps for a texture
RLAPI void SetTextureFilter(Texture2D texture, int filterMode); // Set texture scaling filter mode
RLAPI void SetTextureWrap(Texture2D texture, int wrapMode); // Set texture wrapping mode
+// Texture2D drawing functions
RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
@@ -838,24 +890,30 @@ RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle dest
//------------------------------------------------------------------------------------
// Font Loading and Text Drawing Functions (Module: text)
//------------------------------------------------------------------------------------
+
+// SpriteFont loading/unloading functions
RLAPI SpriteFont GetDefaultFont(void); // Get the default SpriteFont
RLAPI SpriteFont LoadSpriteFont(const char *fileName); // Load SpriteFont from file into GPU memory (VRAM)
-RLAPI SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from TTF font file with generation parameters
+RLAPI SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load SpriteFont from file with extended parameters
RLAPI void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory (VRAM)
+// Text drawing functions
+RLAPI void DrawFPS(int posX, int posY); // Shows current FPS
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
RLAPI void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
float fontSize, int spacing, Color tint);
+
+// Text misc. functions
RLAPI int MeasureText(const char *text, int fontSize); // Measure string width for default font
RLAPI Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing); // Measure string size for SpriteFont
-
-RLAPI 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)
//------------------------------------------------------------------------------------
+
+// Basic geometric 3D shapes drawing functions
RLAPI void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color); // Draw a line in 3D world space
RLAPI void DrawCircle3D(Vector3 center, float radius, Vector3 rotationAxis, float rotationAngle, Color color); // Draw a circle in 3D world space
RLAPI void DrawCube(Vector3 position, float width, float height, float length, Color color); // Draw cube
@@ -876,6 +934,8 @@ RLAPI void DrawGizmo(Vector3 position);
//------------------------------------------------------------------------------------
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
+
+// Model loading/unloading functions
RLAPI Mesh LoadMesh(const char *fileName); // Load mesh from file
RLAPI Mesh LoadMeshEx(int numVertex, float *vData, float *vtData, float *vnData, Color *cData); // Load mesh from vertex data
RLAPI Model LoadModel(const char *fileName); // Load model from file
@@ -885,11 +945,12 @@ RLAPI Model LoadCubicmap(Image cubicmap);
RLAPI void UnloadMesh(Mesh *mesh); // Unload mesh from memory (RAM and/or VRAM)
RLAPI void UnloadModel(Model model); // Unload model from memory (RAM and/or VRAM)
+// Material loading/unloading functions
RLAPI Material LoadMaterial(const char *fileName); // Load material from file
-RLAPI Material LoadMaterialEx(Shader shader, Texture2D diffuse, Color color); // Load material from basic shading data
RLAPI Material LoadDefaultMaterial(void); // Load default material (uses default models shader)
RLAPI void UnloadMaterial(Material material); // Unload material from GPU memory (VRAM)
+// Model drawing functions
RLAPI void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
RLAPI void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis,
float rotationAngle, Vector3 scale, Color tint); // Draw a model with extended parameters
@@ -897,11 +958,11 @@ RLAPI void DrawModelWires(Model model, Vector3 position, float scale, Color tint
RLAPI void DrawModelWiresEx(Model model, Vector3 position, Vector3 rotationAxis,
float rotationAngle, Vector3 scale, Color tint); // Draw a model wires (with texture if set) with extended parameters
RLAPI void DrawBoundingBox(BoundingBox box, Color color); // Draw bounding box (wires)
-
RLAPI void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
RLAPI void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec,
Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
+// Collision detection functions
RLAPI BoundingBox CalculateBoundingBox(Mesh mesh); // Calculate mesh bounding box limits
RLAPI bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB); // Detect collision between two spheres
RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2); // Detect collision between two bounding boxes
@@ -918,6 +979,8 @@ RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight);
// Shaders System Functions (Module: rlgl)
// NOTE: This functions are useless when using OpenGL 1.1
//------------------------------------------------------------------------------------
+
+// Shader loading/unloading functions
RLAPI char *LoadText(const char *fileName); // Load chars array from text file
RLAPI Shader LoadShader(char *vsFileName, char *fsFileName); // Load shader from files and bind default locations
RLAPI void UnloadShader(Shader shader); // Unload shader from GPU memory (VRAM)
@@ -925,38 +988,40 @@ RLAPI void UnloadShader(Shader shader); // Unl
RLAPI Shader GetDefaultShader(void); // Get default shader
RLAPI Texture2D GetDefaultTexture(void); // Get default texture
+// Shader configuration functions
RLAPI int GetShaderLocation(Shader shader, const char *uniformName); // Get shader uniform location
RLAPI void SetShaderValue(Shader shader, int uniformLoc, float *value, int size); // Set shader uniform value (float)
RLAPI void SetShaderValuei(Shader shader, int uniformLoc, int *value, int size); // Set shader uniform value (int)
RLAPI void SetShaderValueMatrix(Shader shader, int uniformLoc, Matrix mat); // Set shader uniform value (matrix 4x4)
-
RLAPI void SetMatrixProjection(Matrix proj); // Set a custom projection matrix (replaces internal projection matrix)
RLAPI void SetMatrixModelview(Matrix view); // Set a custom modelview matrix (replaces internal modelview matrix)
+// Shading begin/end functions
RLAPI void BeginShaderMode(Shader shader); // Begin custom shader drawing
RLAPI void EndShaderMode(void); // End custom shader drawing (use default shader)
RLAPI void BeginBlendMode(int mode); // Begin blending mode (alpha, additive, multiplied)
RLAPI void EndBlendMode(void); // End blending mode (reset to default: alpha blending)
-//------------------------------------------------------------------------------------
-// VR experience Functions (Module: rlgl)
-// NOTE: This functions are useless when using OpenGL 1.1
-//------------------------------------------------------------------------------------
-RLAPI void InitVrDevice(int vdDevice); // Init VR device
-RLAPI void CloseVrDevice(void); // Close VR device
-RLAPI bool IsVrDeviceReady(void); // Detect if VR device is ready
-RLAPI bool IsVrSimulator(void); // Detect if VR simulator is running
-RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
-RLAPI void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
+// VR control functions
+RLAPI void InitVrSimulator(int vrDevice); // Init VR simulator for selected device
+RLAPI void CloseVrSimulator(void); // Close VR simulator for current device
+RLAPI bool IsVrSimulatorReady(void); // Detect if VR simulator is ready
+RLAPI void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
+RLAPI void ToggleVrMode(void); // Enable/Disable VR experience
+RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering
+RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering
//------------------------------------------------------------------------------------
// Audio Loading and Playing Functions (Module: audio)
//------------------------------------------------------------------------------------
+
+// Audio device management functions
RLAPI void InitAudioDevice(void); // Initialize audio device and context
RLAPI void CloseAudioDevice(void); // Close the audio device and context
RLAPI bool IsAudioDeviceReady(void); // Check if audio device has been initialized successfully
RLAPI void SetMasterVolume(float volume); // Set master volume (listener)
+// Wave/Sound loading/unloading functions
RLAPI Wave LoadWave(const char *fileName); // Load wave data from file
RLAPI Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from raw array data
RLAPI Sound LoadSound(const char *fileName); // Load sound from file
@@ -964,6 +1029,8 @@ RLAPI Sound LoadSoundFromWave(Wave wave); // Load so
RLAPI void UpdateSound(Sound sound, const void *data, int samplesCount);// Update sound buffer with new data
RLAPI void UnloadWave(Wave wave); // Unload wave data
RLAPI void UnloadSound(Sound sound); // Unload sound
+
+// Wave/Sound management functions
RLAPI void PlaySound(Sound sound); // Play a sound
RLAPI void PauseSound(Sound sound); // Pause a sound
RLAPI void ResumeSound(Sound sound); // Resume a paused sound
@@ -975,6 +1042,8 @@ RLAPI void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels);
RLAPI Wave WaveCopy(Wave wave); // Copy a wave to a new wave
RLAPI void WaveCrop(Wave *wave, int initSample, int finalSample); // Crop a wave to defined samples range
RLAPI float *GetWaveData(Wave wave); // Get samples data from wave as a floats array
+
+// Music management functions
RLAPI Music LoadMusicStream(const char *fileName); // Load music stream from file
RLAPI void UnloadMusicStream(Music music); // Unload music stream
RLAPI void PlayMusicStream(Music music); // Start music playing
@@ -989,8 +1058,8 @@ RLAPI void SetMusicLoopCount(Music music, float count); // Set mus
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,
+// AudioStream management functions
+RLAPI AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize,
unsigned int channels); // Init audio stream (to stream raw audio pcm data)
RLAPI void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount); // Update audio stream buffers with data
RLAPI void CloseAudioStream(AudioStream stream); // Close audio stream and free memory
diff --git a/src/resources b/src/raylib_icon
index 5c76749d..92ccf3a6 100644
--- a/src/resources
+++ b/src/raylib_icon
Binary files differ
diff --git a/src/raymath.h b/src/raymath.h
index a2263f19..1dbebc07 100644
--- a/src/raymath.h
+++ b/src/raymath.h
@@ -1,6 +1,6 @@
/**********************************************************************************************
*
-* raymath v1.0 - Some useful functions to work with Vector3, Matrix and Quaternions
+* raymath v1.0 - Math functions to work with Vector3, Matrix and Quaternions
*
* CONFIGURATION:
*
@@ -113,44 +113,66 @@ typedef struct Quaternion {
#ifndef RAYMATH_EXTERN_INLINE
//------------------------------------------------------------------------------------
+// Functions Declaration - math utils
+//------------------------------------------------------------------------------------
+RMDEF float Clamp(float value, float min, float max); // Clamp float value
+
+//------------------------------------------------------------------------------------
+// Functions Declaration to work with Vector2
+//------------------------------------------------------------------------------------
+RMDEF Vector2 Vector2Zero(void); // Vector with components value 0.0f
+RMDEF Vector2 Vector2One(void); // Vector with components value 1.0f
+RMDEF Vector2 Vector2Add(Vector2 v1, Vector2 v2); // Add two vectors (v1 + v2)
+RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2); // Subtract two vectors (v1 - v2)
+RMDEF float Vector2Lenght(Vector2 v); // Calculate vector lenght
+RMDEF float Vector2DotProduct(Vector2 v1, Vector2 v2); // Calculate two vectors dot product
+RMDEF float Vector2Distance(Vector2 v1, Vector2 v2); // Calculate distance between two vectors
+RMDEF float Vector2Angle(Vector2 v1, Vector2 v2); // Calculate angle between two vectors in X-axis
+RMDEF void Vector2Scale(Vector2 *v, float scale); // Scale vector (multiply by value)
+RMDEF void Vector2Negate(Vector2 *v); // Negate vector
+RMDEF void Vector2Divide(Vector2 *v, float div); // Divide vector by a float value
+RMDEF void Vector2Normalize(Vector2 *v); // Normalize provided vector
+
+//------------------------------------------------------------------------------------
// Functions Declaration to work with Vector3
//------------------------------------------------------------------------------------
-RMDEF Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors
-RMDEF Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors
-RMDEF Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product
-RMDEF Vector3 VectorPerpendicular(Vector3 v); // Calculate one vector perpendicular vector
-RMDEF float VectorDotProduct(Vector3 v1, Vector3 v2); // Calculate two vectors dot product
-RMDEF float VectorLength(const Vector3 v); // Calculate vector lenght
-RMDEF void VectorScale(Vector3 *v, float scale); // Scale provided vector
-RMDEF void VectorNegate(Vector3 *v); // Negate provided vector (invert direction)
-RMDEF void VectorNormalize(Vector3 *v); // Normalize provided vector
-RMDEF float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points
+RMDEF Vector3 VectorZero(void); // Vector with components value 0.0f
+RMDEF Vector3 VectorOne(void); // Vector with components value 1.0f
+RMDEF Vector3 VectorAdd(Vector3 v1, Vector3 v2); // Add two vectors
+RMDEF Vector3 VectorSubtract(Vector3 v1, Vector3 v2); // Substract two vectors
+RMDEF Vector3 VectorCrossProduct(Vector3 v1, Vector3 v2); // Calculate two vectors cross product
+RMDEF Vector3 VectorPerpendicular(Vector3 v); // Calculate one vector perpendicular vector
+RMDEF float VectorLength(const Vector3 v); // Calculate vector lenght
+RMDEF float VectorDotProduct(Vector3 v1, Vector3 v2); // Calculate two vectors dot product
+RMDEF float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points
+RMDEF void VectorScale(Vector3 *v, float scale); // Scale provided vector
+RMDEF void VectorNegate(Vector3 *v); // Negate provided vector (invert direction)
+RMDEF void VectorNormalize(Vector3 *v); // Normalize provided vector
+RMDEF void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 by a given Matrix
RMDEF Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate linear interpolation between two vectors
-RMDEF Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal
-RMDEF void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 by a given Matrix
-RMDEF Vector3 VectorZero(void); // Return a Vector3 init to zero
-RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2); // Return min value for each pair of components
-RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2); // Return max value for each pair of components
-RMDEF Vector3 Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycenter coords for p in triangle abc
+RMDEF Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal
+RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2); // Return min value for each pair of components
+RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2); // Return max value for each pair of components
+RMDEF Vector3 VectorBarycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycenter coords for p in triangle abc
//------------------------------------------------------------------------------------
// Functions Declaration to work with Matrix
//------------------------------------------------------------------------------------
-RMDEF float MatrixDeterminant(Matrix mat); // Compute matrix determinant
-RMDEF float MatrixTrace(Matrix mat); // Returns the trace of the matrix (sum of the values along the diagonal)
-RMDEF void MatrixTranspose(Matrix *mat); // Transposes provided matrix
-RMDEF void MatrixInvert(Matrix *mat); // Invert provided matrix
-RMDEF void MatrixNormalize(Matrix *mat); // Normalize provided matrix
-RMDEF Matrix MatrixIdentity(void); // Returns identity matrix
-RMDEF Matrix MatrixAdd(Matrix left, Matrix right); // Add two matrices
-RMDEF Matrix MatrixSubstract(Matrix left, Matrix right); // Substract two matrices (left - right)
-RMDEF Matrix MatrixTranslate(float x, float y, float z); // Returns translation matrix
-RMDEF Matrix MatrixRotate(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis (angle in radians)
-RMDEF Matrix MatrixRotateX(float angle); // Returns x-rotation matrix (angle in radians)
-RMDEF Matrix MatrixRotateY(float angle); // Returns y-rotation matrix (angle in radians)
-RMDEF Matrix MatrixRotateZ(float angle); // Returns z-rotation matrix (angle in radians)
-RMDEF Matrix MatrixScale(float x, float y, float z); // Returns scaling matrix
-RMDEF Matrix MatrixMultiply(Matrix left, Matrix right); // Returns two matrix multiplication
+RMDEF float MatrixDeterminant(Matrix mat); // Compute matrix determinant
+RMDEF float MatrixTrace(Matrix mat); // Returns the trace of the matrix (sum of the values along the diagonal)
+RMDEF void MatrixTranspose(Matrix *mat); // Transposes provided matrix
+RMDEF void MatrixInvert(Matrix *mat); // Invert provided matrix
+RMDEF void MatrixNormalize(Matrix *mat); // Normalize provided matrix
+RMDEF Matrix MatrixIdentity(void); // Returns identity matrix
+RMDEF Matrix MatrixAdd(Matrix left, Matrix right); // Add two matrices
+RMDEF Matrix MatrixSubstract(Matrix left, Matrix right); // Substract two matrices (left - right)
+RMDEF Matrix MatrixTranslate(float x, float y, float z); // Returns translation matrix
+RMDEF Matrix MatrixRotate(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis (angle in radians)
+RMDEF Matrix MatrixRotateX(float angle); // Returns x-rotation matrix (angle in radians)
+RMDEF Matrix MatrixRotateY(float angle); // Returns y-rotation matrix (angle in radians)
+RMDEF Matrix MatrixRotateZ(float angle); // Returns z-rotation matrix (angle in radians)
+RMDEF Matrix MatrixScale(float x, float y, float z); // Returns scaling matrix
+RMDEF Matrix MatrixMultiply(Matrix left, Matrix right); // Returns two matrix multiplication
RMDEF Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far); // Returns perspective projection matrix
RMDEF Matrix MatrixPerspective(double fovy, double aspect, double near, double far); // Returns perspective projection matrix
RMDEF Matrix MatrixOrtho(double left, double right, double bottom, double top, double near, double far); // Returns orthographic projection matrix
@@ -159,16 +181,18 @@ RMDEF Matrix MatrixLookAt(Vector3 position, Vector3 target, Vector3 up); // Ret
//------------------------------------------------------------------------------------
// Functions Declaration to work with Quaternions
//------------------------------------------------------------------------------------
-RMDEF float QuaternionLength(Quaternion quat); // Compute the length of a quaternion
-RMDEF void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion
-RMDEF void QuaternionInvert(Quaternion *quat); // Invert provided quaternion
+RMDEF float QuaternionLength(Quaternion quat); // Compute the length of a quaternion
+RMDEF void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion
+RMDEF void QuaternionInvert(Quaternion *quat); // Invert provided quaternion
RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication
RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions
RMDEF Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix
RMDEF Matrix QuaternionToMatrix(Quaternion q); // Returns a matrix for a given quaternion
RMDEF Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns rotation quaternion for an angle and axis
-RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the rotation angle and axis for a given quaternion
-RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix
+RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the rotation angle and axis for a given quaternion
+RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw); // Returns he quaternion equivalent to Euler angles
+RMDEF Vector3 QuaternionToEuler(Quaternion q); // Return the Euler angles equivalent to quaternion (roll, pitch, yaw)
+RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix
#endif // notdef RAYMATH_EXTERN_INLINE
@@ -180,31 +204,112 @@ RMDEF void QuaternionTransform(Quaternion *q, Matrix mat); // Transfo
#include <math.h> // Required for: sinf(), cosf(), tan(), fabs()
//----------------------------------------------------------------------------------
+// Module Functions Definition - Utils math
+//----------------------------------------------------------------------------------
+
+// Clamp float value
+RMDEF float Clamp(float value, float min, float max)
+{
+ const float res = value < min ? min : value;
+ return res > max ? max : res;
+}
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition - Vector2 math
+//----------------------------------------------------------------------------------
+
+// Vector with components value 0.0f
+RMDEF Vector2 Vector2Zero(void) { return (Vector2){ 0.0f, 0.0f }; }
+
+// Vector with components value 1.0f
+RMDEF Vector2 Vector2One(void) { return (Vector2){ 1.0f, 1.0f }; }
+
+// Add two vectors (v1 + v2)
+RMDEF Vector2 Vector2Add(Vector2 v1, Vector2 v2)
+{
+ return (Vector2){ v1.x + v2.x, v1.y + v2.y };
+}
+
+// Subtract two vectors (v1 - v2)
+RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
+{
+ return (Vector2){ v1.x - v2.x, v1.y - v2.y };
+}
+
+// Calculate vector lenght
+RMDEF float Vector2Lenght(Vector2 v)
+{
+ return sqrtf((v.x*v.x) + (v.y*v.y));
+}
+
+// Calculate two vectors dot product
+RMDEF float Vector2DotProduct(Vector2 v1, Vector2 v2)
+{
+ return (v1.x*v2.x + v1.y*v2.y);
+}
+
+// Calculate distance between two vectors
+RMDEF float Vector2Distance(Vector2 v1, Vector2 v2)
+{
+ return sqrtf((v1.x - v2.x)*(v1.x - v2.x) + (v1.y - v2.y)*(v1.y - v2.y));
+}
+
+// Calculate angle from two vectors in X-axis
+RMDEF float Vector2Angle(Vector2 v1, Vector2 v2)
+{
+ float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/PI);
+
+ if (angle < 0) angle += 360.0f;
+
+ return angle;
+}
+
+// Scale vector (multiply by value)
+RMDEF void Vector2Scale(Vector2 *v, float scale)
+{
+ v->x *= scale;
+ v->y *= scale;
+}
+
+// Negate vector
+RMDEF void Vector2Negate(Vector2 *v)
+{
+ v->x = -v->x;
+ v->y = -v->y;
+}
+
+// Divide vector by a float value
+RMDEF void Vector2Divide(Vector2 *v, float div)
+{
+ *v = (Vector2){v->x/div, v->y/div};
+}
+
+// Normalize provided vector
+RMDEF void Vector2Normalize(Vector2 *v)
+{
+ Vector2Divide(v, Vector2Lenght(*v));
+}
+
+//----------------------------------------------------------------------------------
// Module Functions Definition - Vector3 math
//----------------------------------------------------------------------------------
+// Vector with components value 0.0f
+RMDEF Vector3 VectorZero(void) { return (Vector3){ 0.0f, 0.0f, 0.0f }; }
+
+// Vector with components value 1.0f
+RMDEF Vector3 VectorOne(void) { return (Vector3){ 1.0f, 1.0f, 1.0f }; }
+
// Add two vectors
RMDEF Vector3 VectorAdd(Vector3 v1, Vector3 v2)
{
- Vector3 result;
-
- result.x = v1.x + v2.x;
- result.y = v1.y + v2.y;
- result.z = v1.z + v2.z;
-
- return result;
+ return (Vector3){ v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
}
// Substract two vectors
RMDEF Vector3 VectorSubtract(Vector3 v1, Vector3 v2)
{
- Vector3 result;
-
- result.x = v1.x - v2.x;
- result.y = v1.y - v2.y;
- result.z = v1.z - v2.z;
-
- return result;
+ return (Vector3){ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
}
// Calculate two vectors cross product
@@ -233,7 +338,7 @@ RMDEF Vector3 VectorPerpendicular(Vector3 v)
cardinalAxis = (Vector3){0.0f, 1.0f, 0.0f};
}
- if(fabsf(v.z) < min)
+ if (fabsf(v.z) < min)
{
cardinalAxis = (Vector3){0.0f, 0.0f, 1.0f};
}
@@ -243,24 +348,26 @@ RMDEF Vector3 VectorPerpendicular(Vector3 v)
return result;
}
+// Calculate vector lenght
+RMDEF float VectorLength(const Vector3 v)
+{
+ return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
+}
+
// Calculate two vectors dot product
RMDEF float VectorDotProduct(Vector3 v1, Vector3 v2)
{
- float result;
-
- result = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
-
- return result;
+ return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z);
}
-// Calculate vector lenght
-RMDEF float VectorLength(const Vector3 v)
+// Calculate distance between two vectors
+RMDEF float VectorDistance(Vector3 v1, Vector3 v2)
{
- float length;
-
- length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
+ float dx = v2.x - v1.x;
+ float dy = v2.y - v1.y;
+ float dz = v2.z - v1.z;
- return length;
+ return sqrtf(dx*dx + dy*dy + dz*dz);
}
// Scale provided vector
@@ -295,19 +402,18 @@ RMDEF void VectorNormalize(Vector3 *v)
v->z *= ilength;
}
-// Calculate distance between two points
-RMDEF float VectorDistance(Vector3 v1, Vector3 v2)
+// Transforms a Vector3 by a given Matrix
+// TODO: Review math (matrix transpose required?)
+RMDEF void VectorTransform(Vector3 *v, Matrix mat)
{
- float result;
-
- float dx = v2.x - v1.x;
- float dy = v2.y - v1.y;
- float dz = v2.z - v1.z;
-
- result = sqrtf(dx*dx + dy*dy + dz*dz);
+ float x = v->x;
+ float y = v->y;
+ float z = v->z;
- return result;
-}
+ v->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
+ v->y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
+ v->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
+};
// Calculate linear interpolation between two vectors
RMDEF Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount)
@@ -339,27 +445,6 @@ RMDEF Vector3 VectorReflect(Vector3 vector, Vector3 normal)
return result;
}
-// Transforms a Vector3 by a given Matrix
-// TODO: Review math (matrix transpose required?)
-RMDEF void VectorTransform(Vector3 *v, Matrix mat)
-{
- float x = v->x;
- float y = v->y;
- float z = v->z;
-
- v->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
- v->y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
- v->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
-};
-
-// Return a Vector3 init to zero
-RMDEF Vector3 VectorZero(void)
-{
- Vector3 zero = { 0.0f, 0.0f, 0.0f };
-
- return zero;
-}
-
// Return min value for each pair of components
RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2)
{
@@ -386,7 +471,7 @@ RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2)
// Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c)
// NOTE: Assumes P is on the plane of the triangle
-RMDEF Vector3 Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
+RMDEF Vector3 VectorBarycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
{
//Vector v0 = b - a, v1 = c - a, v2 = p - a;
@@ -663,49 +748,6 @@ RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
return result;
}
-/*
-// Another implementation for MatrixRotate...
-RMDEF Matrix MatrixRotate(float angle, float x, float y, float z)
-{
- Matrix result = MatrixIdentity();
-
- float c = cosf(angle); // cosine
- float s = sinf(angle); // sine
- float c1 = 1.0f - c; // 1 - c
-
- float m0 = result.m0, m4 = result.m4, m8 = result.m8, m12 = result.m12,
- m1 = result.m1, m5 = result.m5, m9 = result.m9, m13 = result.m13,
- m2 = result.m2, m6 = result.m6, m10 = result.m10, m14 = result.m14;
-
- // build rotation matrix
- float r0 = x*x*c1 + c;
- float r1 = x*y*c1 + z*s;
- float r2 = x*z*c1 - y*s;
- float r4 = x*y*c1 - z*s;
- float r5 = y*y*c1 + c;
- float r6 = y*z*c1 + x*s;
- float r8 = x*z*c1 + y*s;
- float r9 = y*z*c1 - x*s;
- float r10= z*z*c1 + c;
-
- // multiply rotation matrix
- result.m0 = r0*m0 + r4*m1 + r8*m2;
- result.m1 = r1*m0 + r5*m1 + r9*m2;
- result.m2 = r2*m0 + r6*m1 + r10*m2;
- result.m4 = r0*m4 + r4*m5 + r8*m6;
- result.m5 = r1*m4 + r5*m5 + r9*m6;
- result.m6 = r2*m4 + r6*m5 + r10*m6;
- result.m8 = r0*m8 + r4*m9 + r8*m10;
- result.m9 = r1*m8 + r5*m9 + r9*m10;
- result.m10 = r2*m8 + r6*m9 + r10*m10;
- result.m12 = r0*m12+ r4*m13 + r8*m14;
- result.m13 = r1*m12+ r5*m13 + r9*m14;
- result.m14 = r2*m12+ r6*m13 + r10*m14;
-
- return result;
-}
-*/
-
// Returns x-rotation matrix (angle in radians)
RMDEF Matrix MatrixRotateX(float angle)
{
@@ -1140,6 +1182,51 @@ RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle
*outAngle = resAngle;
}
+// Returns he quaternion equivalent to Euler angles
+RMDEF Quaternion QuaternionFromEuler(float roll, float pitch, float yaw)
+{
+ Quaternion q = { 0 };
+
+ float x0 = cosf(roll*0.5f);
+ float x1 = sinf(roll*0.5f);
+ float y0 = cosf(pitch*0.5f);
+ float y1 = sinf(pitch*0.5f);
+ float z0 = cosf(yaw*0.5f);
+ float z1 = sinf(yaw*0.5f);
+
+ q.x = x1*y0*z0 - x0*y1*z1;
+ q.y = x0*y1*z0 + x1*y0*z1;
+ q.z = x0*y0*z1 - x1*y1*z0;
+ q.w = x0*y0*z0 + x1*y1*z1;
+
+ return q;
+}
+
+// Return the Euler angles equivalent to quaternion (roll, pitch, yaw)
+// NOTE: Angles are returned in a Vector3 struct and in degrees
+RMDEF Vector3 QuaternionToEuler(Quaternion q)
+{
+ Vector3 v = { 0 };
+
+ // roll (x-axis rotation)
+ float x0 = 2.0f*(q.w*q.x + q.y*q.z);
+ float x1 = 1.0f - 2.0f*(q.x*q.x + q.y*q.y);
+ v.x = atan2f(x0, x1)*RAD2DEG;
+
+ // pitch (y-axis rotation)
+ float y0 = 2.0f*(q.w*q.y - q.z*q.x);
+ y0 = y0 > 1.0f ? 1.0f : y0;
+ y0 = y0 < -1.0f ? -1.0f : y0;
+ v.y = asinf(y0)*RAD2DEG;
+
+ // yaw (z-axis rotation)
+ float z0 = 2.0f*(q.w*q.z + q.x*q.y);
+ float z1 = 1.0f - 2.0f*(q.y*q.y + q.z*q.z);
+ v.z = atan2f(z0, z1)*RAD2DEG;
+
+ return v;
+}
+
// Transform a quaternion given a transformation matrix
RMDEF void QuaternionTransform(Quaternion *q, Matrix mat)
{
diff --git a/src/rlgl.c b/src/rlgl.c
index ffc9d741..a40836ca 100644
--- a/src/rlgl.c
+++ b/src/rlgl.c
@@ -2,10 +2,8 @@
*
* rlgl - raylib OpenGL abstraction layer
*
-* DESCRIPTION:
-*
-* rlgl allows usage of OpenGL 1.1 style functions (rlVertex) that are internally mapped to
-* selected OpenGL version (1.1, 2.1, 3.3 Core, ES 2.0).
+* rlgl is a wrapper for multiple OpenGL versions (1.1, 2.1, 3.3 Core, ES 2.0) to
+* pseudo-OpenGL 1.1 style functions (rlVertex, rlTranslate, rlRotate...).
*
* When chosing an OpenGL version greater than OpenGL 1.1, rlgl stores vertex data on internal
* VBO buffers (and VAOs if available). It requires calling 3 functions:
@@ -16,34 +14,19 @@
* CONFIGURATION:
*
* #define GRAPHICS_API_OPENGL_11
-* Use OpenGL 1.1 backend
-*
* #define GRAPHICS_API_OPENGL_21
-* Use OpenGL 2.1 backend
-*
* #define GRAPHICS_API_OPENGL_33
-* Use OpenGL 3.3 Core profile backend
-*
* #define GRAPHICS_API_OPENGL_ES2
-* Use OpenGL ES 2.0 backend
+* Use selected OpenGL backend
*
* #define RLGL_STANDALONE
* Use rlgl as standalone library (no raylib dependency)
*
-* #define RLGL_NO_DISTORTION_SHADER
-* Avoid stereo rendering distortion sahder (shader_distortion.h) inclusion
-*
-* #define SUPPORT_SHADER_DEFAULT / ENABLE_SHADER_DEFAULT
-*
-* #define SUPPORT_SHADER_DISTORTION
-*
+* #define SUPPORT_VR_SIMULATOR
+* Support VR simulation functionality (stereo rendering)
*
-* #define SUPPORT_OCULUS_RIFT_CV1 / RLGL_OCULUS_SUPPORT
-* Enable Oculus Rift CV1 functionality
-*
-* #define SUPPORT_STEREO_RENDERING
-*
-* #define RLGL_NO_DEFAULT_SHADER
+* #define SUPPORT_DISTORTION_SHADER
+* Include stereo rendering distortion shader (shader_distortion.h)
*
* DEPENDENCIES:
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
@@ -52,7 +35,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -71,19 +54,25 @@
*
**********************************************************************************************/
+// Default configuration flags (supported features)
+//-------------------------------------------------
+#define SUPPORT_VR_SIMULATOR
+#define SUPPORT_DISTORTION_SHADER
+//-------------------------------------------------
+
#include "rlgl.h"
#include <stdio.h> // Required for: fopen(), fclose(), fread()... [Used only on LoadText()]
#include <stdlib.h> // Required for: malloc(), free(), rand()
-#include <string.h> // Required for: strcmp(), strlen(), strtok()
+#include <string.h> // Required for: strcmp(), strlen(), strtok() [Used only in extensions loading]
#include <math.h> // Required for: atan2()
-#ifndef RLGL_STANDALONE
+#if !defined(RLGL_STANDALONE)
#include "raymath.h" // Required for: Vector3 and Matrix functions
#endif
#if defined(GRAPHICS_API_OPENGL_11)
- #ifdef __APPLE__
+ #if defined(__APPLE__)
#include <OpenGL/gl.h> // OpenGL 1.1 library for OSX
#else
#include <GL/gl.h> // OpenGL 1.1 library
@@ -95,7 +84,7 @@
#endif
#if defined(GRAPHICS_API_OPENGL_33)
- #ifdef __APPLE__
+ #if defined(__APPLE__)
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
#else
#define GLAD_IMPLEMENTATION
@@ -117,21 +106,10 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() [Used only on TraceLog()]
#endif
-#if !defined(GRAPHICS_API_OPENGL_11) && !defined(RLGL_NO_DISTORTION_SHADER)
+#if !defined(GRAPHICS_API_OPENGL_11) && defined(SUPPORT_DISTORTION_SHADER)
#include "shader_distortion.h" // Distortion shader to be embedded
#endif
-//#define RLGL_OCULUS_SUPPORT // Enable Oculus Rift code
-#if defined(RLGL_OCULUS_SUPPORT)
- #include "external/OculusSDK/LibOVR/Include/OVR_CAPI_GL.h" // Oculus SDK for OpenGL
-#endif
-
-#if defined(RLGL_STANDALONE)
- #define OCULUSAPI
-#else
- #define OCULUSAPI static
-#endif
-
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@@ -187,15 +165,15 @@
#endif
#if defined(GRAPHICS_API_OPENGL_11)
- #define GL_UNSIGNED_SHORT_5_6_5 0x8363
- #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
- #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
+ #define GL_UNSIGNED_SHORT_5_6_5 0x8363
+ #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
+ #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#endif
#if defined(GRAPHICS_API_OPENGL_ES2)
- #define glClearDepth glClearDepthf
- #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER
- #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER
+ #define glClearDepth glClearDepthf
+ #define GL_READ_FRAMEBUFFER GL_FRAMEBUFFER
+ #define GL_DRAW_FRAMEBUFFER GL_FRAMEBUFFER
#endif
// Default vertex attribute names on shader to set location points
@@ -244,6 +222,7 @@ typedef struct DrawCall {
//Guint fboId;
} DrawCall;
+#if defined(SUPPORT_VR_SIMULATOR)
// Head-Mounted-Display device parameters
typedef struct VrDeviceInfo {
int hResolution; // HMD horizontal resolution in pixels
@@ -266,31 +245,6 @@ typedef struct VrStereoConfig {
Matrix eyesProjection[2]; // VR stereo rendering eyes projection matrices
Matrix eyesViewOffset[2]; // VR stereo rendering eyes view offset matrices
} VrStereoConfig;
-
-#if defined(RLGL_OCULUS_SUPPORT)
-typedef struct OculusBuffer {
- ovrTextureSwapChain textureChain;
- GLuint depthId;
- GLuint fboId;
- int width;
- int height;
-} OculusBuffer;
-
-typedef struct OculusMirror {
- ovrMirrorTexture texture;
- GLuint fboId;
- int width;
- int height;
-} OculusMirror;
-
-typedef struct OculusLayer {
- ovrViewScaleDesc viewScaleDesc;
- ovrLayerEyeFov eyeLayer; // layer 0
- //ovrLayerQuad quadLayer; // TODO: layer 1: '2D' quad for GUI
- Matrix eyeProjections[2];
- int width;
- int height;
-} OculusLayer;
#endif
//----------------------------------------------------------------------------------
@@ -305,7 +259,7 @@ static Matrix projection;
static Matrix *currentMatrix;
static int currentMatrixMode;
-static DrawMode currentDrawMode;
+static int currentDrawMode;
static float currentDepth = -1.0f;
@@ -334,7 +288,17 @@ static bool texCompETC1Supported = false; // ETC1 texture compression support
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
static bool texCompPVRTSupported = false; // PVR texture compression support
static bool texCompASTCSupported = false; // ASTC texture compression support
-#endif
+
+#if defined(SUPPORT_VR_SIMULATOR)
+// VR global variables
+static VrDeviceInfo hmd; // Current VR device info
+static VrStereoConfig vrConfig; // VR stereo configuration for simulator
+static bool vrSimulatorReady = false; // VR simulator ready flag
+static bool vrStereoRender = false; // VR stereo rendering enabled/disabled flag
+ // NOTE: This flag is useful to render data over stereo image (i.e. FPS)
+#endif // defined(SUPPORT_VR_SIMULATOR)
+
+#endif // defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
// Extension supported flag: Anisotropic filtering
static bool texAnisotropicFilterSupported = false; // Anisotropic texture filtering support
@@ -343,26 +307,6 @@ static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supp
// Extension supported flag: Clamp mirror wrap mode
static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported
-#if defined(RLGL_OCULUS_SUPPORT)
-// OVR device variables
-static ovrSession session; // Oculus session (pointer to ovrHmdStruct)
-static ovrHmdDesc hmdDesc; // Oculus device descriptor parameters
-static ovrGraphicsLuid luid; // Oculus locally unique identifier for the program (64 bit)
-static OculusLayer layer; // Oculus drawing layer (similar to photoshop)
-static OculusBuffer buffer; // Oculus internal buffers (texture chain and fbo)
-static OculusMirror mirror; // Oculus mirror texture and fbo
-static unsigned int frameIndex = 0; // Oculus frames counter, used to discard frames from chain
-#endif
-
-// VR global variables
-static VrDeviceInfo hmd; // Current VR device info
-static VrStereoConfig vrConfig; // VR stereo configuration for simulator
-static bool vrDeviceReady = false; // VR device ready flag
-static bool vrSimulator = false; // VR simulator enabled flag
-static bool vrEnabled = false; // VR experience enabled (device or simulator)
-static bool vrRendering = true; // VR stereo rendering enabled/disabled flag
- // NOTE: This flag is useful to render data over stereo image (i.e. FPS)
-
#if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: VAO functionality is exposed through extensions (OES)
static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
@@ -373,14 +317,15 @@ static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
// Compressed textures support flags
static bool texCompDXTSupported = false; // DDS texture compression support
-static bool npotSupported = false; // NPOT textures full support
+static bool texNPOTSupported = false; // NPOT textures full support
+static bool texFloatSupported = false; // float textures support (32 bit per channel)
static int blendMode = 0; // Track current blending mode
// White texture useful for plain color polys (required by shader)
static unsigned int whiteTexture;
-// Default framebuffer size (required by Oculus device)
+// Default framebuffer size
static int screenWidth; // Default framebuffer width
static int screenHeight; // Default framebuffer height
@@ -397,35 +342,15 @@ static void UnloadDefaultShader(void); // Unload default shader
static void LoadDefaultBuffers(void); // Load default internal buffers (lines, triangles, quads)
static void UpdateDefaultBuffers(void); // Update default internal buffers (VAOs/VBOs) with vertex data
-static void DrawDefaultBuffers(int eyesCount); // Draw default internal buffers vertex data
+static void DrawDefaultBuffers(void); // Draw default internal buffers vertex data
static void UnloadDefaultBuffers(void); // Unload default internal buffers vertex data from CPU and GPU
-// Configure stereo rendering (including distortion shader) with HMD device parameters
-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);
-#endif
-
-#if defined(RLGL_OCULUS_SUPPORT)
-#if !defined(RLGL_STANDALONE)
-static bool InitOculusDevice(void); // Initialize Oculus device (returns true if success)
-static void CloseOculusDevice(void); // Close Oculus device
-static void UpdateOculusTracking(Camera *camera); // Update Oculus head position-orientation tracking
-static void BeginOculusDrawing(void); // Setup Oculus buffers for drawing
-static void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror
+#if defined(SUPPORT_VR_SIMULATOR)
+static void SetStereoConfig(VrDeviceInfo info); // Configure stereo rendering (including distortion shader) with HMD device parameters
+static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView); // Set internal projection and modelview matrix depending on eye
#endif
-static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height); // Load Oculus required buffers
-static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer); // Unload texture required buffers
-static OculusMirror LoadOculusMirror(ovrSession session, int width, int height); // Load Oculus mirror buffers
-static void UnloadOculusMirror(ovrSession session, OculusMirror mirror); // Unload Oculus mirror buffers
-static void BlitOculusMirror(ovrSession session, OculusMirror mirror); // Copy Oculus screen buffer to mirror texture
-static OculusLayer InitOculusLayer(ovrSession session); // Init Oculus layer (similar to photoshop)
-static Matrix FromOvrMatrix(ovrMatrix4f ovrM); // Convert from Oculus ovrMatrix4f struct to raymath Matrix struct
-#endif
-
-
+#endif // defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
#if defined(GRAPHICS_API_OPENGL_11)
static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight);
@@ -1126,7 +1051,8 @@ void rlglInit(int width, int height)
// NOTE: On OpenGL 3.3 VAO and NPOT are supported by default
vaoSupported = true;
- npotSupported = true;
+ texNPOTSupported = true;
+ texFloatSupported = true;
// 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)
@@ -1195,7 +1121,10 @@ void rlglInit(int width, int height)
// Check NPOT textures support
// NOTE: Only check on OpenGL ES, OpenGL 3.3 has NPOT textures full support as core feature
- if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) npotSupported = true;
+ if (strcmp(extList[i], (const char *)"GL_OES_texture_npot") == 0) texNPOTSupported = true;
+
+ // Check texture float support
+ if (strcmp(extList[i], (const char *)"OES_texture_float") == 0) texFloatSupported = true;
#endif
// DDS texture compression support
@@ -1235,7 +1164,7 @@ void rlglInit(int width, int height)
if (vaoSupported) TraceLog(INFO, "[EXTENSION] VAO extension detected, VAO functions initialized successfully");
else TraceLog(WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported");
- if (npotSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported");
+ if (texNPOTSupported) TraceLog(INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported");
else TraceLog(WARNING, "[EXTENSION] NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
#endif
@@ -1352,9 +1281,7 @@ void rlglDraw(void)
// NOTE: Default buffers upload and draw
UpdateDefaultBuffers();
-
- if (vrEnabled && vrRendering) DrawDefaultBuffers(2);
- else DrawDefaultBuffers(1);
+ DrawDefaultBuffers(); // NOTE: Stereo rendering is checked inside
#endif
}
@@ -1364,21 +1291,17 @@ 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)
- #ifndef __APPLE__
+ #if !defined(__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)
- #ifndef __APPLE__
+ #if defined(GRAPHICS_API_OPENGL_21)
if (GLAD_GL_VERSION_2_1) TraceLog(INFO, "OpenGL 2.1 profile supported");
- #endif
-#elif defined(GRAPHICS_API_OPENGL_33)
- #ifndef __APPLE__
+ #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");
+ #endif
#endif
-#endif
// With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
//if (GLAD_GL_ARB_vertex_array_object) // Use GL_ARB_vertex_array_object
@@ -1409,7 +1332,7 @@ Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view)
}
// Convert image data to OpenGL texture (returns OpenGL valid Id)
-unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount)
+unsigned int rlglLoadTexture(void *data, int width, int height, int format, int mipmapCount)
{
glBindTexture(GL_TEXTURE_2D, 0); // Free any old binding
@@ -1417,39 +1340,39 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
// Check texture format support by OpenGL 1.1 (compressed textures not supported)
#if defined(GRAPHICS_API_OPENGL_11)
- if (textureFormat >= 8)
+ if (format >= COMPRESSED_DXT1_RGB)
{
TraceLog(WARNING, "OpenGL 1.1 does not support GPU compressed texture formats");
return id;
}
#endif
- if ((!texCompDXTSupported) && ((textureFormat == COMPRESSED_DXT1_RGB) || (textureFormat == COMPRESSED_DXT1_RGBA) ||
- (textureFormat == COMPRESSED_DXT3_RGBA) || (textureFormat == COMPRESSED_DXT5_RGBA)))
+ if ((!texCompDXTSupported) && ((format == COMPRESSED_DXT1_RGB) || (format == COMPRESSED_DXT1_RGBA) ||
+ (format == COMPRESSED_DXT3_RGBA) || (format == COMPRESSED_DXT5_RGBA)))
{
TraceLog(WARNING, "DXT compressed texture format not supported");
return id;
}
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if ((!texCompETC1Supported) && (textureFormat == COMPRESSED_ETC1_RGB))
+ if ((!texCompETC1Supported) && (format == COMPRESSED_ETC1_RGB))
{
TraceLog(WARNING, "ETC1 compressed texture format not supported");
return id;
}
- if ((!texCompETC2Supported) && ((textureFormat == COMPRESSED_ETC2_RGB) || (textureFormat == COMPRESSED_ETC2_EAC_RGBA)))
+ if ((!texCompETC2Supported) && ((format == COMPRESSED_ETC2_RGB) || (format == COMPRESSED_ETC2_EAC_RGBA)))
{
TraceLog(WARNING, "ETC2 compressed texture format not supported");
return id;
}
- if ((!texCompPVRTSupported) && ((textureFormat == COMPRESSED_PVRT_RGB) || (textureFormat == COMPRESSED_PVRT_RGBA)))
+ if ((!texCompPVRTSupported) && ((format == COMPRESSED_PVRT_RGB) || (format == COMPRESSED_PVRT_RGBA)))
{
TraceLog(WARNING, "PVRT compressed texture format not supported");
return id;
}
- if ((!texCompASTCSupported) && ((textureFormat == COMPRESSED_ASTC_4x4_RGBA) || (textureFormat == COMPRESSED_ASTC_8x8_RGBA)))
+ if ((!texCompASTCSupported) && ((format == COMPRESSED_ASTC_4x4_RGBA) || (format == COMPRESSED_ASTC_8x8_RGBA)))
{
TraceLog(WARNING, "ASTC compressed texture format not supported");
return id;
@@ -1477,7 +1400,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
// GL_RGBA8 GL_RGBA GL_UNSIGNED_BYTE
// GL_RGB8 GL_RGB GL_UNSIGNED_BYTE
- switch (textureFormat)
+ switch (format)
{
case UNCOMPRESSED_GRAYSCALE:
{
@@ -1503,6 +1426,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
case UNCOMPRESSED_R5G5B5A1: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, (unsigned short *)data); break;
case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
+ case UNCOMPRESSED_R32G32B32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break;
case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break;
@@ -1518,7 +1442,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
}
#elif defined(GRAPHICS_API_OPENGL_11) || defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: on OpenGL ES 2.0 (WebGL), internalFormat must match format and options allowed are: GL_LUMINANCE, GL_RGB, GL_RGBA
- switch (textureFormat)
+ switch (format)
{
case UNCOMPRESSED_GRAYSCALE: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
case UNCOMPRESSED_GRAY_ALPHA: glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, width, height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
@@ -1528,6 +1452,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
case UNCOMPRESSED_R4G4B4A4: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, (unsigned short *)data); break;
case UNCOMPRESSED_R8G8B8A8: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)data); break;
#if defined(GRAPHICS_API_OPENGL_ES2)
+ case UNCOMPRESSED_R32G32B32: if (texFloatSupported) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, (float *)data); break; // Requries extension OES_texture_float
case COMPRESSED_DXT1_RGB: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGB_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT1_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT); break;
case COMPRESSED_DXT3_RGBA: if (texCompDXTSupported) LoadCompressedTexture((unsigned char *)data, width, height, mipmapCount, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT); break; // NOTE: Not supported by WebGL
@@ -1548,7 +1473,7 @@ unsigned int rlglLoadTexture(void *data, int width, int height, int textureForma
// NOTE: glTexParameteri does NOT affect texture uploading, just the way it's used
#if defined(GRAPHICS_API_OPENGL_ES2)
// NOTE: OpenGL ES 2.0 with no GL_OES_texture_npot support (i.e. WebGL) has limited NPOT support, so CLAMP_TO_EDGE must be used
- if (npotSupported)
+ if (texNPOTSupported)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture to repeat on x-axis
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture to repeat on y-axis
@@ -1728,7 +1653,7 @@ void rlglGenerateMipmaps(Texture2D *texture)
if (((texture->width > 0) && ((texture->width & (texture->width - 1)) == 0)) &&
((texture->height > 0) && ((texture->height & (texture->height - 1)) == 0))) texIsPOT = true;
- if ((texIsPOT) || (npotSupported))
+ if ((texIsPOT) || (texNPOTSupported))
{
#if defined(GRAPHICS_API_OPENGL_11)
// Compute required mipmaps
@@ -2018,9 +1943,6 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
#endif
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- int eyesCount = 1;
- if (vrEnabled) eyesCount = 2;
-
glUseProgram(material.shader.id);
// Upload to shader material.colDiffuse
@@ -2153,10 +2075,17 @@ void rlglDrawMesh(Mesh mesh, Material material, Matrix transform)
if (mesh.indices != NULL) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quads.vboId[3]);
}
+ int eyesCount = 1;
+#if defined(SUPPORT_VR_SIMULATOR)
+ if (vrStereoRender) eyesCount = 2;
+#endif
+
for (int eye = 0; eye < eyesCount; eye++)
{
- if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView);
- else modelview = matModelView;
+ if (eyesCount == 1) modelview = matModelView;
+ #if defined(SUPPORT_VR_SIMULATOR)
+ else SetStereoView(eye, matProjection, matModelView);
+ #endif
// Calculate model-view-projection matrix (MVP)
Matrix matMVP = MatrixMultiply(modelview, projection); // Transform to screen-space coordinates
@@ -2324,7 +2253,7 @@ void *rlglReadTexturePixels(Texture2D texture)
pixels = (unsigned char *)malloc(texture.width*texture.height*4*sizeof(unsigned char));
- // NOTE: Despite FBO color texture is RGB, we read data as RGBA... reading as RGB doesn't work... o__O
+ // NOTE: We read data as RGBA because FBO texture is configured as RGBA, despite binding a RGB texture...
glReadPixels(0, 0, texture.width, texture.height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
// Re-attach internal FBO color texture before deleting it
@@ -2617,146 +2546,128 @@ void EndBlendMode(void)
BeginBlendMode(BLEND_ALPHA);
}
-// Init VR device (or simulator)
-// NOTE: If device is not available, it fallbacks to default device (simulator)
+#if defined(SUPPORT_VR_SIMULATOR)
+// Init VR simulator for selected device
// NOTE: It modifies the global variable: VrDeviceInfo hmd
-void InitVrDevice(int vrDevice)
+void InitVrSimulator(int vrDevice)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- switch (vrDevice)
- {
- case HMD_DEFAULT_DEVICE: TraceLog(INFO, "Initializing default VR Device (Oculus Rift CV1)");
- case HMD_OCULUS_RIFT_DK2:
- case HMD_OCULUS_RIFT_CV1:
- {
-#if defined(RLGL_OCULUS_SUPPORT)
- vrDeviceReady = InitOculusDevice();
-#else
- TraceLog(WARNING, "Oculus Rift not supported by default, recompile raylib with Oculus support");
-#endif
- } break;
- case HMD_VALVE_HTC_VIVE:
- case HMD_SAMSUNG_GEAR_VR:
- case HMD_GOOGLE_CARDBOARD:
- case HMD_SONY_PLAYSTATION_VR:
- case HMD_RAZER_OSVR:
- case HMD_FOVE_VR: TraceLog(WARNING, "VR Device not supported");
- default: break;
- }
-
- if (!vrDeviceReady)
- {
- TraceLog(WARNING, "VR Device not found: Initializing VR Simulator (Oculus Rift CV1)");
-
- if (vrDevice == HMD_OCULUS_RIFT_DK2)
- {
- // Oculus Rift DK2 parameters
- hmd.hResolution = 1280; // HMD horizontal resolution in pixels
- hmd.vResolution = 800; // HMD vertical resolution in pixels
- hmd.hScreenSize = 0.14976f; // HMD horizontal size in meters
- hmd.vScreenSize = 0.09356f; // HMD vertical size in meters
- hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
- hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
- hmd.lensSeparationDistance = 0.0635f; // HMD lens separation distance in meters
- hmd.interpupillaryDistance = 0.064f; // HMD IPD (distance between pupils) in meters
- hmd.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0
- hmd.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1
- hmd.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2
- hmd.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3
- hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
- hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
- hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
- hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
- }
- else if ((vrDevice == HMD_DEFAULT_DEVICE) || (vrDevice == HMD_OCULUS_RIFT_CV1))
- {
- // Oculus Rift CV1 parameters
- // NOTE: CV1 represents a complete HMD redesign compared to previous versions,
- // new Fresnel-hybrid-asymmetric lenses have been added and, consequently,
- // previous parameters (DK2) and distortion shader (DK2) doesn't work any more.
- // I just defined a set of parameters for simulator that approximate to CV1 stereo rendering
- // but result is not the same obtained with Oculus PC SDK.
- hmd.hResolution = 2160; // HMD horizontal resolution in pixels
- hmd.vResolution = 1200; // HMD vertical resolution in pixels
- hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters
- hmd.vScreenSize = 0.0669f; // HMD vertical size in meters
- hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
- hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
- hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters
- hmd.interpupillaryDistance = 0.07f; // HMD IPD (distance between pupils) in meters
- hmd.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0
- hmd.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1
- hmd.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2
- hmd.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3
- hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
- hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
- hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
- hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
- }
-
- // Initialize framebuffer and textures for stereo rendering
- // NOTE: screen size should match HMD aspect ratio
- vrConfig.stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight);
-
- // Load distortion shader (initialized by default with Oculus Rift CV1 parameters)
- vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr);
- if (vrConfig.distortionShader.id != 0) LoadDefaultShaderLocations(&vrConfig.distortionShader);
-
- SetStereoConfig(hmd);
-
- vrSimulator = true;
- vrEnabled = true;
- }
+ if (vrDevice == HMD_OCULUS_RIFT_DK2)
+ {
+ // Oculus Rift DK2 parameters
+ hmd.hResolution = 1280; // HMD horizontal resolution in pixels
+ hmd.vResolution = 800; // HMD vertical resolution in pixels
+ hmd.hScreenSize = 0.14976f; // HMD horizontal size in meters
+ hmd.vScreenSize = 0.09356f; // HMD vertical size in meters
+ hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
+ hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
+ hmd.lensSeparationDistance = 0.0635f; // HMD lens separation distance in meters
+ hmd.interpupillaryDistance = 0.064f; // HMD IPD (distance between pupils) in meters
+ hmd.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0
+ hmd.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1
+ hmd.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2
+ hmd.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3
+ hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
+ hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
+ hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
+ hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
+
+ TraceLog(INFO, "Initializing VR Simulator (Oculus Rift DK2)");
+ }
+ else if ((vrDevice == HMD_DEFAULT_DEVICE) || (vrDevice == HMD_OCULUS_RIFT_CV1))
+ {
+ // Oculus Rift CV1 parameters
+ // NOTE: CV1 represents a complete HMD redesign compared to previous versions,
+ // new Fresnel-hybrid-asymmetric lenses have been added and, consequently,
+ // previous parameters (DK2) and distortion shader (DK2) doesn't work any more.
+ // I just defined a set of parameters for simulator that approximate to CV1 stereo rendering
+ // but result is not the same obtained with Oculus PC SDK.
+ hmd.hResolution = 2160; // HMD horizontal resolution in pixels
+ hmd.vResolution = 1200; // HMD vertical resolution in pixels
+ hmd.hScreenSize = 0.133793f; // HMD horizontal size in meters
+ hmd.vScreenSize = 0.0669f; // HMD vertical size in meters
+ hmd.vScreenCenter = 0.04678f; // HMD screen center in meters
+ hmd.eyeToScreenDistance = 0.041f; // HMD distance between eye and display in meters
+ hmd.lensSeparationDistance = 0.07f; // HMD lens separation distance in meters
+ hmd.interpupillaryDistance = 0.07f; // HMD IPD (distance between pupils) in meters
+ hmd.distortionK[0] = 1.0f; // HMD lens distortion constant parameter 0
+ hmd.distortionK[1] = 0.22f; // HMD lens distortion constant parameter 1
+ hmd.distortionK[2] = 0.24f; // HMD lens distortion constant parameter 2
+ hmd.distortionK[3] = 0.0f; // HMD lens distortion constant parameter 3
+ hmd.chromaAbCorrection[0] = 0.996f; // HMD chromatic aberration correction parameter 0
+ hmd.chromaAbCorrection[1] = -0.004f; // HMD chromatic aberration correction parameter 1
+ hmd.chromaAbCorrection[2] = 1.014f; // HMD chromatic aberration correction parameter 2
+ hmd.chromaAbCorrection[3] = 0.0f; // HMD chromatic aberration correction parameter 3
+
+ TraceLog(INFO, "Initializing VR Simulator (Oculus Rift CV1)");
+ }
+ else
+ {
+ TraceLog(WARNING, "VR Simulator doesn't support selected device parameters,");
+ TraceLog(WARNING, "using default VR Simulator parameters");
+ }
+
+ // Initialize framebuffer and textures for stereo rendering
+ // NOTE: screen size should match HMD aspect ratio
+ vrConfig.stereoFbo = rlglLoadRenderTexture(screenWidth, screenHeight);
+
+#if defined(SUPPORT_DISTORTION_SHADER)
+ // Load distortion shader (initialized by default with Oculus Rift CV1 parameters)
+ vrConfig.distortionShader.id = LoadShaderProgram(vDistortionShaderStr, fDistortionShaderStr);
+ if (vrConfig.distortionShader.id != 0) LoadDefaultShaderLocations(&vrConfig.distortionShader);
+#endif
+
+ SetStereoConfig(hmd);
+
+ vrSimulatorReady = true;
#endif
#if defined(GRAPHICS_API_OPENGL_11)
- TraceLog(WARNING, "VR device or simulator not supported on OpenGL 1.1");
+ TraceLog(WARNING, "VR Simulator not supported on OpenGL 1.1");
#endif
}
-// Close VR device (or simulator)
-void CloseVrDevice(void)
+// Close VR simulator for current device
+void CloseVrSimulator(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-#if defined(RLGL_OCULUS_SUPPORT)
- if (vrDeviceReady) CloseOculusDevice();
- else
-#endif
+ if (vrSimulatorReady)
{
rlDeleteRenderTextures(vrConfig.stereoFbo); // Unload stereo framebuffer and texture
+ #if defined(SUPPORT_DISTORTION_SHADER)
UnloadShader(vrConfig.distortionShader); // Unload distortion shader
+ #endif
}
#endif
- vrDeviceReady = false;
-}
-
-// Detect if VR device is available
-bool IsVrDeviceReady(void)
-{
- return (vrDeviceReady && vrEnabled);
}
// Detect if VR simulator is running
-bool IsVrSimulator(void)
+bool IsVrSimulatorReady(void)
{
- return (vrSimulator && vrEnabled);
+#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
+ return vrSimulatorReady;
+#else
+ return false;
+#endif
}
// Enable/Disable VR experience (device or simulator)
void ToggleVrMode(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
- if (vrDeviceReady || vrSimulator) vrEnabled = !vrEnabled;
- else vrEnabled = false;
+ vrSimulatorReady = !vrSimulatorReady;
- if (!vrEnabled)
+ if (!vrSimulatorReady)
{
+ vrStereoRender = false;
+
// Reset viewport and default projection-modelview matrices
rlViewport(0, 0, screenWidth, screenHeight);
projection = MatrixOrtho(0, screenWidth, screenHeight, 0, 0.0f, 1.0f);
MatrixTranspose(&projection);
modelview = MatrixIdentity();
}
+ else vrStereoRender = true;
#endif
}
@@ -2764,37 +2675,29 @@ void ToggleVrMode(void)
// NOTE: Camera (position, target, up) gets update with head tracking information
void UpdateVrTracking(Camera *camera)
{
-#if defined(RLGL_OCULUS_SUPPORT)
- if (vrDeviceReady) UpdateOculusTracking(camera);
-#endif
+ // TODO: Simulate 1st person camera system
}
// Begin Oculus drawing configuration
void BeginVrDrawing(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-#if defined(RLGL_OCULUS_SUPPORT)
- if (vrDeviceReady)
- {
- BeginOculusDrawing();
- }
- else
-#endif
+ if (vrSimulatorReady)
{
// Setup framebuffer for stereo rendering
rlEnableRenderTexture(vrConfig.stereoFbo.id);
- }
- // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
- // and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
- // - Require OculusBuffer format to be OVR_FORMAT_R8G8B8A8_UNORM_SRGB
- // - Do NOT enable GL_FRAMEBUFFER_SRGB
- //glEnable(GL_FRAMEBUFFER_SRGB);
+ // NOTE: If your application is configured to treat the texture as a linear format (e.g. GL_RGBA)
+ // and performs linear-to-gamma conversion in GLSL or does not care about gamma-correction, then:
+ // - Require OculusBuffer format to be OVR_FORMAT_R8G8B8A8_UNORM_SRGB
+ // - Do NOT enable GL_FRAMEBUFFER_SRGB
+ //glEnable(GL_FRAMEBUFFER_SRGB);
- //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
- rlClearScreenBuffers(); // Clear current framebuffer(s)
-
- vrRendering = true;
+ //glViewport(0, 0, buffer.width, buffer.height); // Useful if rendering to separate framebuffers (every eye)
+ rlClearScreenBuffers(); // Clear current framebuffer(s)
+
+ vrStereoRender = true;
+ }
#endif
}
@@ -2802,18 +2705,13 @@ void BeginVrDrawing(void)
void EndVrDrawing(void)
{
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
-#if defined(RLGL_OCULUS_SUPPORT)
- if (vrDeviceReady)
- {
- EndOculusDrawing();
- }
- else
-#endif
+ if (vrSimulatorReady)
{
- // Unbind current framebuffer
- rlDisableRenderTexture();
+ vrStereoRender = false; // Disable stereo render
+
+ rlDisableRenderTexture(); // Unbind current framebuffer
- rlClearScreenBuffers(); // Clear current framebuffer
+ rlClearScreenBuffers(); // Clear current framebuffer
// Set viewport to default framebuffer size (screen size)
rlViewport(0, 0, screenWidth, screenHeight);
@@ -2825,8 +2723,12 @@ void EndVrDrawing(void)
rlMatrixMode(RL_MODELVIEW); // Enable internal modelview matrix
rlLoadIdentity(); // Reset internal modelview matrix
+#if defined(SUPPORT_DISTORTION_SHADER)
// Draw RenderTexture (stereoFbo) using distortion shader
currentShader = vrConfig.distortionShader;
+#else
+ currentShader = GetDefaultShader();
+#endif
rlEnableTexture(vrConfig.stereoFbo.texture.id);
@@ -2855,17 +2757,24 @@ void EndVrDrawing(void)
rlDisableTexture();
+ // Update and draw render texture fbo with distortion to backbuffer
UpdateDefaultBuffers();
- DrawDefaultBuffers(1);
-
+ DrawDefaultBuffers();
+
+ // Restore defaultShader
currentShader = defaultShader;
- }
- rlDisableDepthTest();
-
- vrRendering = false;
+ // Reset viewport and default projection-modelview matrices
+ rlViewport(0, 0, screenWidth, screenHeight);
+ projection = MatrixOrtho(0, screenWidth, screenHeight, 0, 0.0f, 1.0f);
+ MatrixTranspose(&projection);
+ modelview = MatrixIdentity();
+
+ rlDisableDepthTest();
+ }
#endif
}
+#endif // SUPPORT_VR_SIMULATOR
//----------------------------------------------------------------------------------
// Module specific Functions Definition
@@ -3405,14 +3314,21 @@ static void UpdateDefaultBuffers(void)
// Draw default internal buffers vertex data
// NOTE: We draw in this order: lines, triangles, quads
-static void DrawDefaultBuffers(int eyesCount)
+static void DrawDefaultBuffers()
{
Matrix matProjection = projection;
Matrix matModelView = modelview;
+
+ int eyesCount = 1;
+#if defined(SUPPORT_VR_SIMULATOR)
+ if (vrStereoRender) eyesCount = 2;
+#endif
for (int eye = 0; eye < eyesCount; eye++)
{
+ #if defined(SUPPORT_VR_SIMULATOR)
if (eyesCount == 2) SetStereoView(eye, matProjection, matModelView);
+ #endif
// Set current shader and upload current MVP matrix
if ((lines.vCounter > 0) || (triangles.vCounter > 0) || (quads.vCounter > 0))
@@ -3618,6 +3534,7 @@ static void UnloadDefaultBuffers(void)
free(quads.indices);
}
+#if defined(SUPPORT_VR_SIMULATOR)
// Configure stereo rendering (including distortion shader) with HMD device parameters
static void SetStereoConfig(VrDeviceInfo hmd)
{
@@ -3652,6 +3569,7 @@ static void SetStereoConfig(VrDeviceInfo hmd)
TraceLog(DEBUG, "VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
TraceLog(DEBUG, "VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
+#if defined(SUPPORT_DISTORTION_SHADER)
// Update distortion shader with lens and distortion-scale parameters
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "leftLensCenter"), leftLensCenter, 2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "rightLensCenter"), rightLensCenter, 2);
@@ -3662,6 +3580,7 @@ static void SetStereoConfig(VrDeviceInfo hmd)
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "scaleIn"), scaleIn, 2);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "hmdWarpParam"), hmd.distortionK, 4);
SetShaderValue(vrConfig.distortionShader, GetShaderLocation(vrConfig.distortionShader, "chromaAbParam"), hmd.chromaAbCorrection, 4);
+#endif
// Fovy is normally computed with: 2*atan2(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)*RAD2DEG
// ...but with lens distortion it is increased (see Oculus SDK Documentation)
@@ -3693,48 +3612,22 @@ static void SetStereoConfig(VrDeviceInfo hmd)
// Set internal projection and modelview matrix depending on eyes tracking data
static void SetStereoView(int eye, Matrix matProjection, Matrix matModelView)
{
- if (vrEnabled)
- {
- Matrix eyeProjection = matProjection;
- Matrix eyeModelView = matModelView;
+ Matrix eyeProjection = matProjection;
+ Matrix eyeModelView = matModelView;
-#if defined(RLGL_OCULUS_SUPPORT)
- if (vrDeviceReady)
- {
- rlViewport(layer.eyeLayer.Viewport[eye].Pos.x, layer.eyeLayer.Viewport[eye].Pos.y,
- layer.eyeLayer.Viewport[eye].Size.w, layer.eyeLayer.Viewport[eye].Size.h);
-
- Quaternion eyeRenderPose = (Quaternion){ layer.eyeLayer.RenderPose[eye].Orientation.x,
- layer.eyeLayer.RenderPose[eye].Orientation.y,
- layer.eyeLayer.RenderPose[eye].Orientation.z,
- layer.eyeLayer.RenderPose[eye].Orientation.w };
- QuaternionInvert(&eyeRenderPose);
- Matrix eyeOrientation = QuaternionToMatrix(eyeRenderPose);
- Matrix eyeTranslation = MatrixTranslate(-layer.eyeLayer.RenderPose[eye].Position.x,
- -layer.eyeLayer.RenderPose[eye].Position.y,
- -layer.eyeLayer.RenderPose[eye].Position.z);
-
- Matrix eyeView = MatrixMultiply(eyeTranslation, eyeOrientation); // Matrix containing eye-head movement
- eyeModelView = MatrixMultiply(matModelView, eyeView); // Combine internal camera matrix (modelview) wih eye-head movement
-
- eyeProjection = layer.eyeProjections[eye];
- }
- else
-#endif
- {
- // Setup viewport and projection/modelview matrices using tracking data
- rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight);
+ // Setup viewport and projection/modelview matrices using tracking data
+ rlViewport(eye*screenWidth/2, 0, screenWidth/2, screenHeight);
- // Apply view offset to modelview matrix
- eyeModelView = MatrixMultiply(matModelView, vrConfig.eyesViewOffset[eye]);
+ // Apply view offset to modelview matrix
+ eyeModelView = MatrixMultiply(matModelView, vrConfig.eyesViewOffset[eye]);
- eyeProjection = vrConfig.eyesProjection[eye];
- }
+ eyeProjection = vrConfig.eyesProjection[eye];
- SetMatrixModelview(eyeModelView);
- SetMatrixProjection(eyeProjection);
- }
+ SetMatrixModelview(eyeModelView);
+ SetMatrixProjection(eyeProjection);
}
+#endif // defined(SUPPORT_VR_SIMULATOR)
+
#endif //defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
#if defined(GRAPHICS_API_OPENGL_11)
@@ -3864,304 +3757,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight)
}
#endif
-#if defined(RLGL_OCULUS_SUPPORT)
-// Initialize Oculus device (returns true if success)
-OCULUSAPI bool InitOculusDevice(void)
-{
- bool oculusReady = false;
-
- ovrResult result = ovr_Initialize(NULL);
-
- if (OVR_FAILURE(result)) TraceLog(WARNING, "OVR: Could not initialize Oculus device");
- else
- {
- result = ovr_Create(&session, &luid);
- if (OVR_FAILURE(result))
- {
- TraceLog(WARNING, "OVR: Could not create Oculus session");
- ovr_Shutdown();
- }
- else
- {
- hmdDesc = ovr_GetHmdDesc(session);
-
- TraceLog(INFO, "OVR: Product Name: %s", hmdDesc.ProductName);
- TraceLog(INFO, "OVR: Manufacturer: %s", hmdDesc.Manufacturer);
- TraceLog(INFO, "OVR: Product ID: %i", hmdDesc.ProductId);
- TraceLog(INFO, "OVR: Product Type: %i", hmdDesc.Type);
- //TraceLog(INFO, "OVR: Serial Number: %s", hmdDesc.SerialNumber);
- TraceLog(INFO, "OVR: Resolution: %ix%i", hmdDesc.Resolution.w, hmdDesc.Resolution.h);
-
- // NOTE: Oculus mirror is set to defined screenWidth and screenHeight...
- // ...ideally, it should be (hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2)
-
- // Initialize Oculus Buffers
- layer = InitOculusLayer(session);
- buffer = LoadOculusBuffer(session, layer.width, layer.height);
- mirror = LoadOculusMirror(session, hmdDesc.Resolution.w/2, hmdDesc.Resolution.h/2); // NOTE: hardcoded...
- layer.eyeLayer.ColorTexture[0] = buffer.textureChain; //SetOculusLayerTexture(eyeLayer, buffer.textureChain);
-
- // Recenter OVR tracking origin
- ovr_RecenterTrackingOrigin(session);
-
- oculusReady = true;
- vrEnabled = true;
- }
- }
-
- return oculusReady;
-}
-
-// Close Oculus device (and unload buffers)
-OCULUSAPI void CloseOculusDevice(void)
-{
- UnloadOculusMirror(session, mirror); // Unload Oculus mirror buffer
- UnloadOculusBuffer(session, buffer); // Unload Oculus texture buffers
-
- ovr_Destroy(session); // Free Oculus session data
- ovr_Shutdown(); // Close Oculus device connection
-}
-
-// Update Oculus head position-orientation tracking
-OCULUSAPI void UpdateOculusTracking(Camera *camera)
-{
- frameIndex++;
-
- ovrPosef eyePoses[2];
- ovr_GetEyePoses(session, frameIndex, ovrTrue, layer.viewScaleDesc.HmdToEyeOffset, eyePoses, &layer.eyeLayer.SensorSampleTime);
-
- layer.eyeLayer.RenderPose[0] = eyePoses[0];
- layer.eyeLayer.RenderPose[1] = eyePoses[1];
-
- // TODO: Update external camera with eyePoses data (position, orientation)
- // NOTE: We can simplify to simple camera if we consider IPD and HMD device configuration again later
- // it will be useful for the user to draw, lets say, billboards oriented to camera
-
- // Get session status information
- ovrSessionStatus sessionStatus;
- ovr_GetSessionStatus(session, &sessionStatus);
-
- if (sessionStatus.ShouldQuit) TraceLog(WARNING, "OVR: Session should quit...");
- if (sessionStatus.ShouldRecenter) ovr_RecenterTrackingOrigin(session);
- //if (sessionStatus.HmdPresent) // HMD is present.
- //if (sessionStatus.DisplayLost) // HMD was unplugged or the display driver was manually disabled or encountered a TDR.
- //if (sessionStatus.HmdMounted) // HMD is on the user's head.
- //if (sessionStatus.IsVisible) // the game or experience has VR focus and is visible in the HMD.
-}
-
-// Setup Oculus buffers for drawing
-OCULUSAPI void BeginOculusDrawing(void)
-{
- GLuint currentTexId;
- int currentIndex;
-
- ovr_GetTextureSwapChainCurrentIndex(session, buffer.textureChain, &currentIndex);
- ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, currentIndex, &currentTexId);
-
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, currentTexId, 0);
- //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, buffer.depthId, 0); // Already binded
-}
-
-// Finish Oculus drawing and blit framebuffer to mirror
-OCULUSAPI void EndOculusDrawing(void)
-{
- // Unbind current framebuffer (Oculus buffer)
- glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
- ovr_CommitTextureSwapChain(session, buffer.textureChain);
-
- ovrLayerHeader *layers = &layer.eyeLayer.Header;
- ovr_SubmitFrame(session, frameIndex, &layer.viewScaleDesc, &layers, 1);
-
- // Blit mirror texture to back buffer
- BlitOculusMirror(session, mirror);
-}
-
-// Load Oculus required buffers: texture-swap-chain, fbo, texture-depth
-static OculusBuffer LoadOculusBuffer(ovrSession session, int width, int height)
-{
- OculusBuffer buffer;
- buffer.width = width;
- buffer.height = height;
-
- // Create OVR texture chain
- ovrTextureSwapChainDesc desc = {};
- desc.Type = ovrTexture_2D;
- desc.ArraySize = 1;
- desc.Width = width;
- desc.Height = height;
- desc.MipLevels = 1;
- desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB; // Requires glEnable(GL_FRAMEBUFFER_SRGB);
- desc.SampleCount = 1;
- desc.StaticImage = ovrFalse;
-
- ovrResult result = ovr_CreateTextureSwapChainGL(session, &desc, &buffer.textureChain);
-
- if (!OVR_SUCCESS(result)) TraceLog(WARNING, "OVR: Failed to create swap textures buffer");
-
- int textureCount = 0;
- ovr_GetTextureSwapChainLength(session, buffer.textureChain, &textureCount);
-
- if (!OVR_SUCCESS(result) || !textureCount) TraceLog(WARNING, "OVR: Unable to count swap chain textures");
-
- for (int i = 0; i < textureCount; ++i)
- {
- GLuint chainTexId;
- ovr_GetTextureSwapChainBufferGL(session, buffer.textureChain, i, &chainTexId);
- glBindTexture(GL_TEXTURE_2D, chainTexId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
-
- glBindTexture(GL_TEXTURE_2D, 0);
-
- /*
- // Setup framebuffer object (using depth texture)
- glGenFramebuffers(1, &buffer.fboId);
- glGenTextures(1, &buffer.depthId);
- glBindTexture(GL_TEXTURE_2D, buffer.depthId);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, buffer.width, buffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
- */
-
- // Setup framebuffer object (using depth renderbuffer)
- glGenFramebuffers(1, &buffer.fboId);
- glGenRenderbuffers(1, &buffer.depthId);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer.fboId);
- glBindRenderbuffer(GL_RENDERBUFFER, buffer.depthId);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, buffer.width, buffer.height);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
- glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, buffer.depthId);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-
- return buffer;
-}
-
-// Unload texture required buffers
-static void UnloadOculusBuffer(ovrSession session, OculusBuffer buffer)
-{
- if (buffer.textureChain)
- {
- ovr_DestroyTextureSwapChain(session, buffer.textureChain);
- buffer.textureChain = NULL;
- }
-
- if (buffer.depthId != 0) glDeleteTextures(1, &buffer.depthId);
- if (buffer.fboId != 0) glDeleteFramebuffers(1, &buffer.fboId);
-}
-
-// Load Oculus mirror buffers
-static OculusMirror LoadOculusMirror(ovrSession session, int width, int height)
-{
- OculusMirror mirror;
- mirror.width = width;
- mirror.height = height;
-
- ovrMirrorTextureDesc mirrorDesc;
- memset(&mirrorDesc, 0, sizeof(mirrorDesc));
- mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
- mirrorDesc.Width = mirror.width;
- mirrorDesc.Height = mirror.height;
-
- if (!OVR_SUCCESS(ovr_CreateMirrorTextureGL(session, &mirrorDesc, &mirror.texture))) TraceLog(WARNING, "Could not create mirror texture");
-
- glGenFramebuffers(1, &mirror.fboId);
-
- return mirror;
-}
-
-// Unload Oculus mirror buffers
-static void UnloadOculusMirror(ovrSession session, OculusMirror mirror)
-{
- if (mirror.fboId != 0) glDeleteFramebuffers(1, &mirror.fboId);
- if (mirror.texture) ovr_DestroyMirrorTexture(session, mirror.texture);
-}
-
-// Copy Oculus screen buffer to mirror texture
-static void BlitOculusMirror(ovrSession session, OculusMirror mirror)
-{
- GLuint mirrorTextureId;
-
- ovr_GetMirrorTextureBufferGL(session, mirror.texture, &mirrorTextureId);
-
- glBindFramebuffer(GL_READ_FRAMEBUFFER, mirror.fboId);
- glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mirrorTextureId, 0);
-#if defined(GRAPHICS_API_OPENGL_33)
- // NOTE: glBlitFramebuffer() requires extension: GL_EXT_framebuffer_blit (not available in OpenGL ES 2.0)
- glBlitFramebuffer(0, 0, mirror.width, mirror.height, 0, mirror.height, mirror.width, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
-#endif
- glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
-}
-
-// Init Oculus layer (similar to photoshop)
-static OculusLayer InitOculusLayer(ovrSession session)
-{
- OculusLayer layer = { 0 };
-
- layer.viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
-
- memset(&layer.eyeLayer, 0, sizeof(ovrLayerEyeFov));
- layer.eyeLayer.Header.Type = ovrLayerType_EyeFov;
- layer.eyeLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
-
- ovrEyeRenderDesc eyeRenderDescs[2];
-
- for (int eye = 0; eye < 2; eye++)
- {
- eyeRenderDescs[eye] = ovr_GetRenderDesc(session, eye, hmdDesc.DefaultEyeFov[eye]);
- ovrMatrix4f ovrPerspectiveProjection = ovrMatrix4f_Projection(eyeRenderDescs[eye].Fov, 0.01f, 10000.0f, ovrProjection_None); //ovrProjection_ClipRangeOpenGL);
- layer.eyeProjections[eye] = FromOvrMatrix(ovrPerspectiveProjection); // NOTE: struct ovrMatrix4f { float M[4][4] } --> struct Matrix
-
- layer.viewScaleDesc.HmdToEyeOffset[eye] = eyeRenderDescs[eye].HmdToEyeOffset;
- layer.eyeLayer.Fov[eye] = eyeRenderDescs[eye].Fov;
-
- ovrSizei eyeSize = ovr_GetFovTextureSize(session, eye, layer.eyeLayer.Fov[eye], 1.0f);
- layer.eyeLayer.Viewport[eye].Size = eyeSize;
- layer.eyeLayer.Viewport[eye].Pos.x = layer.width;
- layer.eyeLayer.Viewport[eye].Pos.y = 0;
-
- layer.height = eyeSize.h; //std::max(renderTargetSize.y, (uint32_t)eyeSize.h);
- layer.width += eyeSize.w;
- }
-
- return layer;
-}
-
-// Convert from Oculus ovrMatrix4f struct to raymath Matrix struct
-static Matrix FromOvrMatrix(ovrMatrix4f ovrmat)
-{
- Matrix rmat;
-
- rmat.m0 = ovrmat.M[0][0];
- rmat.m1 = ovrmat.M[1][0];
- rmat.m2 = ovrmat.M[2][0];
- rmat.m3 = ovrmat.M[3][0];
- rmat.m4 = ovrmat.M[0][1];
- rmat.m5 = ovrmat.M[1][1];
- rmat.m6 = ovrmat.M[2][1];
- rmat.m7 = ovrmat.M[3][1];
- rmat.m8 = ovrmat.M[0][2];
- rmat.m9 = ovrmat.M[1][2];
- rmat.m10 = ovrmat.M[2][2];
- rmat.m11 = ovrmat.M[3][2];
- rmat.m12 = ovrmat.M[0][3];
- rmat.m13 = ovrmat.M[1][3];
- rmat.m14 = ovrmat.M[2][3];
- rmat.m15 = ovrmat.M[3][3];
-
- MatrixTranspose(&rmat);
-
- return rmat;
-}
-#endif
-
#if defined(RLGL_STANDALONE)
// Output a trace log message
// NOTE: Expected msgType: (0)Info, (1)Error, (2)Warning
diff --git a/src/rlgl.h b/src/rlgl.h
index 41f671e6..6d6ad516 100644
--- a/src/rlgl.h
+++ b/src/rlgl.h
@@ -2,8 +2,8 @@
*
* rlgl - raylib OpenGL abstraction layer
*
-* rlgl allows usage of OpenGL 1.1 style functions (rlVertex) that are internally mapped to
-* selected OpenGL version (1.1, 2.1, 3.3 Core, ES 2.0).
+* rlgl is a wrapper for multiple OpenGL versions (1.1, 2.1, 3.3 Core, ES 2.0) to
+* pseudo-OpenGL 1.1 style functions (rlVertex, rlTranslate, rlRotate...).
*
* When chosing an OpenGL version greater than OpenGL 1.1, rlgl stores vertex data on internal
* VBO buffers (and VAOs if available). It requires calling 3 functions:
@@ -11,20 +11,33 @@
* rlglDraw() - Process internal buffers and send required draw calls
* rlglClose() - De-initialize internal buffers data and other auxiliar resources
*
-* External libs:
+* CONFIGURATION:
+*
+* #define GRAPHICS_API_OPENGL_11
+* #define GRAPHICS_API_OPENGL_21
+* #define GRAPHICS_API_OPENGL_33
+* #define GRAPHICS_API_OPENGL_ES2
+* Use selected OpenGL graphics backend, should be supported by platform
+* Those preprocessor defines are only used on rlgl module, if OpenGL version is
+* required by any other module, use rlGetVersion() tocheck it
+*
+* #define RLGL_STANDALONE
+* Use rlgl as standalone library (no raylib dependency)
+*
+* #define SUPPORT_VR_SIMULATION / SUPPORT_STEREO_RENDERING
+* Support VR simulation functionality (stereo rendering)
+*
+* #define SUPPORT_SHADER_DISTORTION
+* Include stereo rendering distortion shader (shader_distortion.h)
+*
+* DEPENDENCIES:
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
* GLAD - OpenGL extensions loading (OpenGL 3.3 Core only)
*
-* Module Configuration Flags:
-* GRAPHICS_API_OPENGL_11 - Use OpenGL 1.1 backend
-* GRAPHICS_API_OPENGL_21 - Use OpenGL 2.1 backend
-* GRAPHICS_API_OPENGL_33 - Use OpenGL 3.3 Core profile backend
-* GRAPHICS_API_OPENGL_ES2 - Use OpenGL ES 2.0 backend
-*
-* RLGL_STANDALONE - Use rlgl as standalone library (no raylib dependency)
*
+* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -46,28 +59,14 @@
#ifndef RLGL_H
#define RLGL_H
-//#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line
-
-#ifndef RLGL_STANDALONE
- #include "raylib.h" // Required for: Model, Shader, Texture2D
- #include "utils.h" // Required for: TraceLog()
-#endif
-
-#ifdef RLGL_STANDALONE
+#if defined(RLGL_STANDALONE)
#define RAYMATH_STANDALONE
+#else
+ #include "raylib.h" // Required for: Model, Shader, Texture2D, TraceLog()
#endif
#include "raymath.h" // Required for: Vector3, Matrix
-// Select desired OpenGL version
-// NOTE: Those preprocessor defines are only used on rlgl module,
-// if OpenGL version is required by any other module, it uses rlGetVersion()
-
-// Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33
-//#define GRAPHICS_API_OPENGL_11 // Only available on PLATFORM_DESKTOP
-//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP and RLGL_OCULUS_SUPPORT
-//#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB
-
// Security check in case no GRAPHICS_API_OPENGL_* defined
#if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_21) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2)
#define GRAPHICS_API_OPENGL_11
@@ -124,15 +123,21 @@
#define RL_WRAP_CLAMP 0x812F // GL_CLAMP_TO_EDGE
#define RL_WRAP_CLAMP_MIRROR 0x8742 // GL_MIRROR_CLAMP_EXT
+// Matrix modes (equivalent to OpenGL)
+#define RL_MODELVIEW 0x1700 // GL_MODELVIEW
+#define RL_PROJECTION 0x1701 // GL_PROJECTION
+#define RL_TEXTURE 0x1702 // GL_TEXTURE
+
+// Primitive assembly draw modes
+#define RL_LINES 0x0001 // GL_LINES
+#define RL_TRIANGLES 0x0004 // GL_TRIANGLES
+#define RL_QUADS 0x0007 // GL_QUADS
+
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef enum { OPENGL_11 = 1, OPENGL_21, OPENGL_33, OPENGL_ES_20 } GlVersion;
-typedef enum { RL_PROJECTION, RL_MODELVIEW, RL_TEXTURE } MatrixMode;
-
-typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
-
typedef unsigned char byte;
#if defined(RLGL_STANDALONE)
@@ -148,28 +153,23 @@ typedef unsigned char byte;
unsigned char b;
unsigned char a;
} Color;
+
+ // Texture2D type
+ // NOTE: Data stored in GPU memory
+ typedef struct Texture2D {
+ unsigned int id; // OpenGL texture id
+ int width; // Texture base width
+ int height; // Texture base height
+ int mipmaps; // Mipmap levels, 1 by default
+ int format; // Data format (TextureFormat)
+ } Texture2D;
- // Texture formats (support depends on OpenGL version)
- typedef enum {
- UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
- UNCOMPRESSED_GRAY_ALPHA,
- 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;
+ // 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;
// Vertex data definning a mesh
typedef struct Mesh {
@@ -211,23 +211,6 @@ typedef unsigned char byte;
int mapTexture2Loc; // Map texture uniform location point (default-texture-unit = 2)
} Shader;
- // Texture2D type
- // NOTE: Data stored in GPU memory
- typedef struct Texture2D {
- unsigned int id; // OpenGL texture id
- int width; // Texture base width
- int height; // Texture base height
- int mipmaps; // Mipmap levels, 1 by default
- int format; // Data format (TextureFormat)
- } 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)
@@ -250,6 +233,38 @@ typedef unsigned char byte;
Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees)
} Camera;
+
+ // TraceLog message types
+ typedef enum {
+ INFO = 0,
+ ERROR,
+ WARNING,
+ DEBUG,
+ OTHER
+ } TraceLogType;
+
+ // Texture formats (support depends on OpenGL version)
+ typedef enum {
+ UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
+ UNCOMPRESSED_GRAY_ALPHA,
+ UNCOMPRESSED_R5G6B5, // 16 bpp
+ UNCOMPRESSED_R8G8B8, // 24 bpp
+ UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
+ UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
+ UNCOMPRESSED_R8G8B8A8, // 32 bpp
+ UNCOMPRESSED_R32G32B32, // 32 bit per channel (float) - HDR
+ COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
+ COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
+ COMPRESSED_DXT3_RGBA, // 8 bpp
+ COMPRESSED_DXT5_RGBA, // 8 bpp
+ COMPRESSED_ETC1_RGB, // 4 bpp
+ COMPRESSED_ETC2_RGB, // 4 bpp
+ COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
+ COMPRESSED_PVRT_RGB, // 4 bpp
+ COMPRESSED_PVRT_RGBA, // 4 bpp
+ COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
+ COMPRESSED_ASTC_8x8_RGBA // 2 bpp
+ } TextureFormat;
// Texture parameters: filter mode
// NOTE 1: Filtering considers mipmaps if available in the texture
@@ -264,13 +279,18 @@ typedef unsigned char byte;
} TextureFilterMode;
// Texture parameters: wrap mode
- typedef enum { WRAP_REPEAT = 0, WRAP_CLAMP, WRAP_MIRROR } TextureWrapMode;
+ typedef enum {
+ WRAP_REPEAT = 0,
+ WRAP_CLAMP,
+ WRAP_MIRROR
+ } TextureWrapMode;
// Color blending modes (pre-defined)
- typedef enum { BLEND_ALPHA = 0, BLEND_ADDITIVE, BLEND_MULTIPLIED } BlendMode;
-
- // TraceLog message types
- typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
+ typedef enum {
+ BLEND_ALPHA = 0,
+ BLEND_ADDITIVE,
+ BLEND_MULTIPLIED
+ } BlendMode;
// VR Head Mounted Display devices
typedef enum {
@@ -349,7 +369,7 @@ void rlglClose(void); // De-init rlgl
void rlglDraw(void); // Draw VAO/VBO
void rlglLoadExtensions(void *loader); // Load OpenGL extensions
-unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount); // Load texture in GPU
+unsigned int rlglLoadTexture(void *data, int width, int height, int format, int mipmapCount); // Load texture in GPU
RenderTexture2D rlglLoadRenderTexture(int width, int height); // Load a texture to be used for rendering (fbo with color and depth attachments)
void rlglUpdateTexture(unsigned int id, int width, int height, int format, const void *data); // Update GPU texture with new data
void rlglGenerateMipmaps(Texture2D *texture); // Generate mipmap data for selected texture
@@ -399,19 +419,12 @@ void EndBlendMode(void); // End blend
void TraceLog(int msgType, const char *text, ...);
float *MatrixToFloat(Matrix mat);
-void InitVrDevice(int vrDevice); // Init VR device
-void CloseVrDevice(void); // Close VR device
-bool IsVrDeviceReady(void); // Detect if VR device is ready
-bool IsVrSimulator(void); // Detect if VR simulator is running
+void InitVrSimulator(int vrDevice); // Init VR simulator for selected device
+void CloseVrSimulator(void); // Close VR simulator for current device
void UpdateVrTracking(Camera *camera); // Update VR tracking (position and orientation) and camera
void ToggleVrMode(void); // Enable/Disable VR experience (device or simulator)
-
-// Oculus Rift API for direct access the device (no simulator)
-bool InitOculusDevice(void); // Initialize Oculus device (returns true if success)
-void CloseOculusDevice(void); // Close Oculus device
-void UpdateOculusTracking(Camera *camera); // Update Oculus head position-orientation tracking (and camera)
-void BeginOculusDrawing(void); // Setup Oculus buffers for drawing
-void EndOculusDrawing(void); // Finish Oculus drawing and blit framebuffer to mirror
+void BeginVrDrawing(void); // Begin VR stereo rendering
+void EndVrDrawing(void); // End VR stereo rendering
#endif
#ifdef __cplusplus
diff --git a/src/rres.h b/src/rres.h
index 362da10d..65ebdbba 100644
--- a/src/rres.h
+++ b/src/rres.h
@@ -1,8 +1,6 @@
/**********************************************************************************************
*
-* rres - raylib Resource custom format management functions
-*
-* Basic functions to load/save rRES resource files
+* rres v1.0 - raylib resource (rRES) custom fileformat management functions
*
* CONFIGURATION:
*
diff --git a/src/shapes.c b/src/shapes.c
index a42b0551..2a924476 100644
--- a/src/shapes.c
+++ b/src/shapes.c
@@ -13,7 +13,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -57,7 +57,7 @@
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
-// No private (static) functions in this module (.c file)
+static float EaseCubicInOut(float t, float b, float c, float d); // Cubic easing
//----------------------------------------------------------------------------------
// Module Functions Definition
@@ -103,6 +103,64 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
rlEnd();
}
+// Draw a line defining thickness
+void DrawLineEx(Vector2 startPos, Vector2 endPos, float thick, Color color)
+{
+ if (startPos.x > endPos.x)
+ {
+ Vector2 tempPos = startPos;
+ startPos = endPos;
+ endPos = tempPos;
+ }
+
+ float dx = endPos.x - startPos.x;
+ float dy = endPos.y - startPos.y;
+
+ float d = sqrtf(dx*dx + dy*dy);
+ float angle = asinf(dy/d);
+
+ rlEnableTexture(GetDefaultTexture().id);
+
+ rlPushMatrix();
+ rlTranslatef((float)startPos.x, (float)startPos.y, 0);
+ rlRotatef(-RAD2DEG*angle, 0, 0, 1);
+ rlTranslatef(0, -thick/2.0f, 0);
+
+ rlBegin(RL_QUADS);
+ rlColor4ub(color.r, color.g, color.b, color.a);
+ rlNormal3f(0.0f, 0.0f, 1.0f);
+
+ rlVertex2f(0.0f, 0.0f);
+ rlVertex2f(0.0f, thick);
+ rlVertex2f(d, thick);
+ rlVertex2f(d, 0.0f);
+ rlEnd();
+ rlPopMatrix();
+
+ rlDisableTexture();
+}
+
+// Draw line using cubic-bezier curves in-out
+void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color)
+{
+ #define LINE_DIVISIONS 24 // Bezier line divisions
+
+ Vector2 previous = startPos;
+ Vector2 current;
+
+ for (int i = 1; i <= LINE_DIVISIONS; i++)
+ {
+ // Cubic easing in-out
+ // NOTE: Easing is calcutated only for y position value
+ current.y = EaseCubicInOut(i, startPos.y, endPos.y - startPos.y, LINE_DIVISIONS);
+ current.x = previous.x + (endPos.x - startPos.x)/LINE_DIVISIONS;
+
+ DrawLineEx(previous, current, thick, color);
+
+ previous = current;
+ }
+}
+
// Draw a color-filled circle
void DrawCircle(int centerX, int centerY, float radius, Color color)
{
@@ -560,3 +618,15 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
return retRec;
}
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Definition
+//----------------------------------------------------------------------------------
+
+// Cubic easing in-out
+// NOTE: Required for DrawLineBezier()
+static float EaseCubicInOut(float t, float b, float c, float d)
+{
+ if ((t/=d/2) < 1) return (c/2*t*t*t + b);
+ return (c/2*((t-=2)*t*t + 2) + b);
+} \ No newline at end of file
diff --git a/src/text.c b/src/text.c
index 18ebf482..027701de 100644
--- a/src/text.c
+++ b/src/text.c
@@ -5,12 +5,11 @@
* CONFIGURATION:
*
* #define SUPPORT_FILEFORMAT_FNT
-* #define SUPPORT_FILEFORMAT_TTF / INCLUDE_STB_TRUETYPE
-* #define SUPPORT_FILEFORMAT_IMAGE_FONT
+* #define SUPPORT_FILEFORMAT_TTF
* Selected desired fileformats to be supported for loading. Some of those formats are
* supported by default, to remove support, just comment unrequired #define in this module
*
-* #define INCLUDE_DEFAULT_FONT / SUPPORT_DEFAULT_FONT
+* #define SUPPORT_DEFAULT_FONT
*
* DEPENDENCIES:
* stb_truetype - Load TTF file and rasterize characters data
@@ -18,7 +17,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -37,6 +36,13 @@
*
**********************************************************************************************/
+// Default supported features
+//-------------------------------------
+#define SUPPORT_DEFAULT_FONT
+#define SUPPORT_FILEFORMAT_FNT
+#define SUPPORT_FILEFORMAT_TTF
+//-------------------------------------
+
#include "raylib.h"
#include <stdlib.h> // Required for: malloc(), free()
@@ -44,12 +50,14 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fscanf(), feof(), rewind(), fgets()
-#include "utils.h" // Required for: GetExtension()
+#include "utils.h" // Required for: fopen() Android mapping
-// Following libs are used on LoadTTF()
-#define STBTT_STATIC // Define stb_truetype functions static to this module
-#define STB_TRUETYPE_IMPLEMENTATION
-#include "external/stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
+#if defined(SUPPORT_FILEFORMAT_TTF)
+ // Following libs are used on LoadTTF()
+ #define STBTT_STATIC // Define stb_truetype functions static to this module
+ #define STB_TRUETYPE_IMPLEMENTATION
+ #include "external/stb_truetype.h" // Required for: stbtt_BakeFontBitmap()
+#endif
// Rectangle packing functions (not used at the moment)
//#define STB_RECT_PACK_IMPLEMENTATION
@@ -61,8 +69,6 @@
#define MAX_FORMATTEXT_LENGTH 64
#define MAX_SUBTEXT_LENGTH 64
-#define BIT_CHECK(a,b) ((a) & (1 << (b)))
-
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
@@ -71,8 +77,10 @@
//----------------------------------------------------------------------------------
// Global variables
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_DEFAULT_FONT)
static SpriteFont defaultFont; // Default font provided by raylib
// NOTE: defaultFont is loaded on InitWindow and disposed on CloseWindow [module: core]
+#endif
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by text)
@@ -85,18 +93,28 @@ static SpriteFont defaultFont; // Default font provided by raylib
static int GetCharIndex(SpriteFont font, int letter);
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)
+#if defined(SUPPORT_FILEFORMAT_FNT)
static SpriteFont LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
+#endif
+#if defined(SUPPORT_FILEFORMAT_TTF)
static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, int *fontChars); // Load spritefont from TTF data
+#endif
+#if defined(SUPPORT_DEFAULT_FONT)
extern void LoadDefaultFont(void);
extern void UnloadDefaultFont(void);
+#endif
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_DEFAULT_FONT)
+
+// Load raylib default font
extern void LoadDefaultFont(void)
{
+ #define BIT_CHECK(a,b) ((a) & (1 << (b)))
+
// NOTE: Using UTF8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement
// http://www.utf8-chartable.de/unicode-utf8-table.pl
@@ -241,16 +259,23 @@ extern void LoadDefaultFont(void)
TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id);
}
+// Unload raylib default font
extern void UnloadDefaultFont(void)
{
UnloadTexture(defaultFont.texture);
free(defaultFont.chars);
}
+#endif // SUPPORT_DEFAULT_FONT
// Get the default font, useful to be used with extended parameters
SpriteFont GetDefaultFont()
{
+#if defined(SUPPORT_DEFAULT_FONT)
return defaultFont;
+#else
+ SpriteFont font = { 0 };
+ return font;
+#endif
}
// Load SpriteFont from file into GPU memory (VRAM)
@@ -264,10 +289,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
SpriteFont spriteFont = { 0 };
// Check file extension
- if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName); // TODO: DELETE... SOON...
- else if (strcmp(GetExtension(fileName),"ttf") == 0) spriteFont = LoadSpriteFontTTF(fileName, DEFAULT_TTF_FONTSIZE, 0, NULL);
- else if (strcmp(GetExtension(fileName),"fnt") == 0) spriteFont = LoadBMFont(fileName);
- else if (strcmp(GetExtension(fileName),"rres") == 0)
+ if (IsFileExtension(fileName, ".rres"))
{
// TODO: Read multiple resource blocks from file (RRES_FONT_IMAGE, RRES_FONT_CHARDATA)
RRES rres = LoadResource(fileName, 0);
@@ -293,6 +315,12 @@ SpriteFont LoadSpriteFont(const char *fileName)
// TODO: Do not free rres.data memory (chars info data!)
//UnloadResource(rres[0]);
}
+#if defined(SUPPORT_FILEFORMAT_TTF)
+ else if (IsFileExtension(fileName, ".ttf")) spriteFont = LoadSpriteFontEx(fileName, DEFAULT_TTF_FONTSIZE, 0, NULL);
+#endif
+#if defined(SUPPORT_FILEFORMAT_FNT)
+ else if (IsFileExtension(fileName, ".fnt")) spriteFont = LoadBMFont(fileName);
+#endif
else
{
Image image = LoadImage(fileName);
@@ -313,11 +341,12 @@ SpriteFont LoadSpriteFont(const char *fileName)
// Load SpriteFont from TTF font file with generation parameters
// NOTE: You can pass an array with desired characters, those characters should be available in the font
// if array is NULL, default char set is selected 32..126
-SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount, int *fontChars)
+SpriteFont LoadSpriteFontEx(const char *fileName, int fontSize, int charsCount, int *fontChars)
{
SpriteFont spriteFont = { 0 };
- if (strcmp(GetExtension(fileName),"ttf") == 0)
+#if defined(SUPPORT_FILEFORMAT_TTF)
+ if (IsFileExtension(fileName, ".ttf"))
{
if ((fontChars == NULL) || (charsCount == 0))
{
@@ -331,6 +360,7 @@ SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount,
}
else spriteFont = LoadTTF(fileName, fontSize, charsCount, fontChars);
}
+#endif
if (spriteFont.texture.id == 0)
{
@@ -345,7 +375,7 @@ SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int charsCount,
void UnloadSpriteFont(SpriteFont spriteFont)
{
// NOTE: Make sure spriteFont is not default font (fallback)
- if (spriteFont.texture.id != defaultFont.texture.id)
+ if (spriteFont.texture.id != GetDefaultFont().texture.id)
{
UnloadTexture(spriteFont.texture);
free(spriteFont.chars);
@@ -360,7 +390,7 @@ void UnloadSpriteFont(SpriteFont spriteFont)
void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
{
// Check if default font has been loaded
- if (defaultFont.texture.id != 0)
+ if (GetDefaultFont().texture.id != 0)
{
Vector2 position = { (float)posX, (float)posY };
@@ -413,7 +443,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
index = GetCharIndex(spriteFont, (int)letter + 64);
i++;
}
- else index = GetCharIndex(spriteFont, (int)text[i]);
+ else index = GetCharIndex(spriteFont, (unsigned char)text[i]);
DrawTexturePro(spriteFont.texture, spriteFont.chars[index].rec,
(Rectangle){ position.x + textOffsetX + spriteFont.chars[index].offsetX*scaleFactor,
@@ -471,7 +501,7 @@ int MeasureText(const char *text, int fontSize)
Vector2 vec = { 0.0f, 0.0f };
// Check if default font has been loaded
- if (defaultFont.texture.id != 0)
+ if (GetDefaultFont().texture.id != 0)
{
int defaultFontSize = 10; // Default Font chars height in pixel
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
@@ -688,144 +718,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
return spriteFont;
}
-// Load a rBMF font file (raylib BitMap Font)
-static SpriteFont LoadRBMF(const char *fileName)
-{
- // rBMF Info Header (16 bytes)
- typedef struct {
- char id[4]; // rBMF file identifier
- char version; // rBMF file version
- // 4 MSB --> main version
- // 4 LSB --> subversion
- char firstChar; // First character in the font
- // NOTE: Depending on charDataType, it could be useless
- short imgWidth; // Image width - always POT (power-of-two)
- short imgHeight; // Image height - always POT (power-of-two)
- short numChars; // Number of characters contained
- short charHeight; // Characters height - the same for all characters
- char compType; // Compression type:
- // 4 MSB --> image data compression
- // 4 LSB --> chars data compression
- char charsDataType; // Char data type provided
- } rbmfInfoHeader;
-
- SpriteFont spriteFont = { 0 };
-
- // REMOVE SOON!!!
-/*
- rbmfInfoHeader rbmfHeader;
- unsigned int *rbmfFileData = NULL;
- unsigned char *rbmfCharWidthData = NULL;
-
- int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
-
- FILE *rbmfFile = fopen(fileName, "rb"); // Define a pointer to bitmap file and open it in read-binary mode
-
- if (rbmfFile == NULL)
- {
- TraceLog(WARNING, "[%s] rBMF font file could not be opened, using default font", fileName);
-
- spriteFont = GetDefaultFont();
- }
- else
- {
- fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
-
- TraceLog(DEBUG, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
-
- spriteFont.numChars = (int)rbmfHeader.numChars;
-
- int numPixelBits = rbmfHeader.imgWidth*rbmfHeader.imgHeight/32;
-
- rbmfFileData = (unsigned int *)malloc(numPixelBits*sizeof(unsigned int));
-
- for (int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile);
-
- 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);
-
- // Re-construct image from rbmfFileData
- //-----------------------------------------
- Color *imagePixels = (Color *)malloc(rbmfHeader.imgWidth*rbmfHeader.imgHeight*sizeof(Color));
-
- for (int i = 0; i < rbmfHeader.imgWidth*rbmfHeader.imgHeight; i++) imagePixels[i] = BLANK; // Initialize array
-
- int counter = 0; // Font data elements counter
-
- // Fill image data (convert from bit to pixel!)
- for (int i = 0; i < rbmfHeader.imgWidth*rbmfHeader.imgHeight; i += 32)
- {
- for (int j = 31; j >= 0; j--)
- {
- if (BIT_CHECK(rbmfFileData[counter], j)) imagePixels[i+j] = WHITE;
- }
-
- 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);
-
- // Create spritefont with all data read from rbmf file
- spriteFont.texture = LoadTextureFromImage(image);
- UnloadImage(image); // Unload image data
-
- //TraceLog(INFO, "[%s] Starting chars set reconstruction", fileName);
-
- // Get characters data using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
- spriteFont.chars = (CharInfo *)malloc(spriteFont.charsCount*sizeof(CharInfo));
-
- int currentLine = 0;
- int currentPosX = charsDivisor;
- int testPosX = charsDivisor;
-
- for (int i = 0; i < spriteFont.charsCount; i++)
- {
- spriteFont.chars[i].value = (int)rbmfHeader.firstChar + i;
-
- spriteFont.chars[i].rec.x = currentPosX;
- spriteFont.chars[i].rec.y = charsDivisor + currentLine*((int)rbmfHeader.charHeight + charsDivisor);
- spriteFont.chars[i].rec.width = (int)rbmfCharWidthData[i];
- spriteFont.chars[i].rec.height = (int)rbmfHeader.charHeight;
-
- // NOTE: On image based fonts (XNA style), character offsets and xAdvance are not required (set to 0)
- spriteFont.chars[i].offsetX = 0;
- spriteFont.chars[i].offsetY = 0;
- spriteFont.chars[i].advanceX = 0;
-
- testPosX += (spriteFont.chars[i].rec.width + charsDivisor);
-
- if (testPosX > spriteFont.texture.width)
- {
- currentLine++;
- currentPosX = 2*charsDivisor + (int)rbmfCharWidthData[i];
- testPosX = currentPosX;
-
- spriteFont.chars[i].rec.x = charsDivisor;
- spriteFont.chars[i].rec.y = charsDivisor + currentLine*(rbmfHeader.charHeight + charsDivisor);
- }
- else currentPosX = testPosX;
- }
-
- spriteFont.baseSize = spriteFont.charRecs[0].height;
-
- TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
- }
-
- fclose(rbmfFile);
-
- free(rbmfFileData); // Now we can free loaded data from RAM memory
- free(rbmfCharWidthData);
-*/
-
- return spriteFont;
-}
-
+#if defined(SUPPORT_FILEFORMAT_FNT)
// Load a BMFont file (AngelCode font file)
static SpriteFont LoadBMFont(const char *fileName)
{
@@ -943,7 +836,9 @@ static SpriteFont LoadBMFont(const char *fileName)
return font;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_TTF)
// 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, int charsCount, int *fontChars)
@@ -1035,4 +930,5 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int charsCount, in
free(charData);
return font;
-} \ No newline at end of file
+}
+#endif
diff --git a/src/textures.c b/src/textures.c
index 7db3bf56..81d36ef8 100644
--- a/src/textures.c
+++ b/src/textures.c
@@ -4,24 +4,24 @@
*
* CONFIGURATION:
*
-* #define SUPPORT_STB_IMAGE / INCLUDE_STB_IMAGE
-*
-* #define SUPPORT_FILEFORMAT_BMP / SUPPORT_LOAD_BMP
-* #define SUPPORT_FILEFORMAT_PNG / SUPPORT_LOAD_PNG
+* #define SUPPORT_FILEFORMAT_BMP
+* #define SUPPORT_FILEFORMAT_PNG
* #define SUPPORT_FILEFORMAT_TGA
-* #define SUPPORT_FILEFORMAT_JPG / ENABLE_LOAD_JPG
+* #define SUPPORT_FILEFORMAT_JPG
* #define SUPPORT_FILEFORMAT_GIF
+* #define SUPPORT_FILEFORMAT_PSD
* #define SUPPORT_FILEFORMAT_HDR
-* #define SUPPORT_FILEFORMAT_DDS / ENABLE_LOAD_DDS
+* #define SUPPORT_FILEFORMAT_DDS
* #define SUPPORT_FILEFORMAT_PKM
* #define SUPPORT_FILEFORMAT_KTX
* #define SUPPORT_FILEFORMAT_PVR
* #define SUPPORT_FILEFORMAT_ASTC
-* Selected desired fileformats to be supported for loading. Some of those formats are
+* Selecte desired fileformats to be supported for image data loading. Some of those formats are
* supported by default, to remove support, just comment unrequired #define in this module
*
-* #define SUPPORT_IMAGE_RESIZE / INCLUDE_STB_IMAGE_RESIZE
* #define SUPPORT_IMAGE_MANIPULATION
+* Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop...
+* If not defined only three image editing functions supported: ImageFormat(), ImageAlphaMask(), ImageToPOT()
*
* DEPENDENCIES:
* stb_image - Multiple image formats loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
@@ -31,7 +31,7 @@
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -50,6 +50,13 @@
*
**********************************************************************************************/
+// Default configuration flags (supported features)
+//-------------------------------------------------
+#define SUPPORT_FILEFORMAT_PNG
+#define SUPPORT_FILEFORMAT_HDR
+#define SUPPORT_IMAGE_MANIPULATION
+//-------------------------------------------------
+
#include "raylib.h"
#include <stdlib.h> // Required for: malloc(), free()
@@ -59,25 +66,48 @@
// Required for: rlglLoadTexture() rlDeleteTextures(),
// rlglGenerateMipmaps(), some funcs for DrawTexturePro()
-#include "utils.h" // Required for: fopen() Android mapping, TraceLog()
+#include "utils.h" // Required for: fopen() Android mapping
+
+// Support only desired texture formats on stb_image
+#if !defined(SUPPORT_FILEFORMAT_BMP)
+ #define STBI_NO_BMP
+#endif
+#if !defined(SUPPORT_FILEFORMAT_PNG)
+ #define STBI_NO_PNG
+#endif
+#if !defined(SUPPORT_FILEFORMAT_TGA)
+ #define STBI_NO_TGA
+#endif
+#if !defined(SUPPORT_FILEFORMAT_JPG)
+ #define STBI_NO_JPEG // Image format .jpg and .jpeg
+#endif
+#if !defined(SUPPORT_FILEFORMAT_PSD)
+ #define STBI_NO_PSD
+#endif
+#if !defined(SUPPORT_FILEFORMAT_GIF)
+ #define STBI_NO_GIF
+#endif
+#if !defined(SUPPORT_FILEFORMAT_HDR)
+ #define STBI_NO_HDR
+#endif
-// 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
+// Image fileformats not supported by default
#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()
- // NOTE: Used for image scaling on ImageResize()
+#if (defined(SUPPORT_FILEFORMAT_BMP) || defined(SUPPORT_FILEFORMAT_PNG) || defined(SUPPORT_FILEFORMAT_TGA) || \
+ defined(SUPPORT_FILEFORMAT_JPG) || defined(SUPPORT_FILEFORMAT_PSD) || defined(SUPPORT_FILEFORMAT_GIF) || \
+ defined(SUPPORT_FILEFORMAT_HDR))
+ #define STB_IMAGE_IMPLEMENTATION
+ #include "external/stb_image.h" // Required for: stbi_load_from_file()
+ // NOTE: Used to read image data (multiple formats support)
+#endif
+
+#if defined(SUPPORT_IMAGE_MANIPULATION)
+ #define STB_IMAGE_RESIZE_IMPLEMENTATION
+ #include "external/stb_image_resize.h" // Required for: stbir_resize_uint8()
+ // NOTE: Used for image scaling on ImageResize()
+#endif
//----------------------------------------------------------------------------------
// Defines and Macros
@@ -102,11 +132,21 @@
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_FILEFORMAT_DDS)
static Image LoadDDS(const char *fileName); // Load DDS file
+#endif
+#if defined(SUPPORT_FILEFORMAT_PKM)
static Image LoadPKM(const char *fileName); // Load PKM file
+#endif
+#if defined(SUPPORT_FILEFORMAT_KTX)
static Image LoadKTX(const char *fileName); // Load KTX file
+#endif
+#if defined(SUPPORT_FILEFORMAT_PVR)
static Image LoadPVR(const char *fileName); // Load PVR file
+#endif
+#if defined(SUPPORT_FILEFORMAT_ASTC)
static Image LoadASTC(const char *fileName); // Load ASTC file
+#endif
//----------------------------------------------------------------------------------
// Module Functions Definition
@@ -115,36 +155,47 @@ static Image LoadASTC(const char *fileName); // Load ASTC file
// Load image from file into CPU memory (RAM)
Image LoadImage(const char *fileName)
{
- Image image;
+ Image image = { 0 };
- // Initialize image default values
- image.data = NULL;
- image.width = 0;
- image.height = 0;
- image.mipmaps = 0;
- image.format = 0;
+ if (IsFileExtension(fileName, ".rres"))
+ {
+ RRES rres = LoadResource(fileName, 0);
+
+ // NOTE: Parameters for RRES_TYPE_IMAGE are: width, height, format, mipmaps
+
+ if (rres[0].type == RRES_TYPE_IMAGE) image = LoadImagePro(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3);
+ else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName);
- if ((strcmp(GetExtension(fileName),"png") == 0) ||
- (strcmp(GetExtension(fileName),"bmp") == 0) ||
- (strcmp(GetExtension(fileName),"tga") == 0) ||
- (strcmp(GetExtension(fileName),"jpg") == 0)
-#ifndef STBI_NO_GIF
- || (strcmp(GetExtension(fileName),"gif") == 0)
+ UnloadResource(rres);
+ }
+ else if ((IsFileExtension(fileName, ".png"))
+#if defined(SUPPORT_FILEFORMAT_BMP)
+ || (IsFileExtension(fileName, ".bmp"))
+#endif
+#if defined(SUPPORT_FILEFORMAT_TGA)
+ || (IsFileExtension(fileName, ".tga"))
#endif
-#ifndef STBI_NO_PSD
- || (strcmp(GetExtension(fileName),"psd") == 0)
+#if defined(SUPPORT_FILEFORMAT_JPG)
+ || (IsFileExtension(fileName, ".jpg"))
#endif
-#ifndef STBI_NO_PIC
- || (strcmp(GetExtension(fileName),"pic") == 0)
+#if defined(SUPPORT_FILEFORMAT_DDS)
+ || (IsFileExtension(fileName, ".gif"))
+#endif
+#if defined(SUPPORT_FILEFORMAT_PSD)
+ || (IsFileExtension(fileName, ".psd"))
#endif
)
{
int imgWidth = 0;
int imgHeight = 0;
int imgBpp = 0;
+
+ FILE *imFile = fopen(fileName, "rb");
// NOTE: Using stb_image to load images (Supports: BMP, TGA, PNG, JPG, ...)
- image.data = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 0);
+ image.data = stbi_load_from_file(imFile, &imgWidth, &imgHeight, &imgBpp, 0);
+
+ fclose(imFile);
image.width = imgWidth;
image.height = imgHeight;
@@ -155,22 +206,49 @@ Image LoadImage(const char *fileName)
else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8;
else if (imgBpp == 4) image.format = UNCOMPRESSED_R8G8B8A8;
}
- else if (strcmp(GetExtension(fileName),"dds") == 0) image = LoadDDS(fileName);
- else if (strcmp(GetExtension(fileName),"pkm") == 0) image = LoadPKM(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);
- else if (strcmp(GetExtension(fileName),"rres") == 0)
+#if defined(SUPPORT_FILEFORMAT_HDR)
+ else if (IsFileExtension(fileName, ".hdr"))
{
- RRES rres = LoadResource(fileName, 0);
-
- // NOTE: Parameters for RRES_TYPE_IMAGE are: width, height, format, mipmaps
-
- if (rres[0].type == RRES_TYPE_IMAGE) image = LoadImagePro(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3);
- else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName);
-
- UnloadResource(rres);
+ int imgBpp = 0;
+
+ FILE *imFile = fopen(fileName, "rb");
+
+ stbi_set_flip_vertically_on_load(true);
+
+ // Load 32 bit per channel floats data
+ image.data = stbi_loadf_from_file(imFile, &image.width, &image.height, &imgBpp, 0);
+
+ stbi_set_flip_vertically_on_load(false);
+
+ fclose(imFile);
+
+ image.mipmaps = 1;
+
+ if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32;
+ else
+ {
+ // TODO: Support different number of channels at 32 bit float
+ TraceLog(WARNING, "[%s] Image fileformat not supported (only 3 channel 32 bit floats)", fileName);
+ UnloadImage(image);
+ }
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_DDS)
+ else if (IsFileExtension(fileName, ".dds")) image = LoadDDS(fileName);
+#endif
+#if defined(SUPPORT_FILEFORMAT_PKM)
+ else if (IsFileExtension(fileName, ".pkm")) image = LoadPKM(fileName);
+#endif
+#if defined(SUPPORT_FILEFORMAT_KTX)
+ else if (IsFileExtension(fileName, ".ktx")) image = LoadKTX(fileName);
+#endif
+#if defined(SUPPORT_FILEFORMAT_PVR)
+ else if (IsFileExtension(fileName, ".pvr")) image = LoadPVR(fileName);
+#endif
+#if defined(SUPPORT_FILEFORMAT_ASTC)
+ else if (IsFileExtension(fileName, ".astc")) image = LoadASTC(fileName);
+#endif
+ else TraceLog(WARNING, "[%s] Image fileformat not supported", 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", fileName);
@@ -225,13 +303,7 @@ Image LoadImagePro(void *data, int width, int height, int format)
// Load an image from RAW file data
Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize)
{
- Image image;
-
- image.data = NULL;
- image.width = 0;
- image.height = 0;
- image.mipmaps = 0;
- image.format = 0;
+ Image image = { 0 };
FILE *rawFile = fopen(fileName, "rb");
@@ -254,6 +326,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
case UNCOMPRESSED_R5G5B5A1: image.data = (unsigned short *)malloc(size); break; // 16 bpp (1 bit alpha)
case UNCOMPRESSED_R4G4B4A4: image.data = (unsigned short *)malloc(size); break; // 16 bpp (4 bit alpha)
case UNCOMPRESSED_R8G8B8A8: image.data = (unsigned char *)malloc(size*4); size *= 4; break; // 32 bpp
+ case UNCOMPRESSED_R32G32B32: image.data = (float *)malloc(size*12); size *= 12; break; // 4 byte per channel (12 byte)
default: TraceLog(WARNING, "Image format not suported"); break;
}
@@ -285,7 +358,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
// Load texture from file into GPU memory (VRAM)
Texture2D LoadTexture(const char *fileName)
{
- Texture2D texture;
+ Texture2D texture = { 0 };
Image image = LoadImage(fileName);
@@ -294,11 +367,7 @@ Texture2D LoadTexture(const char *fileName)
texture = LoadTextureFromImage(image);
UnloadImage(image);
}
- else
- {
- TraceLog(WARNING, "Texture could not be created");
- texture.id = 0;
- }
+ else TraceLog(WARNING, "Texture could not be created");
return texture;
}
@@ -307,14 +376,7 @@ Texture2D LoadTexture(const char *fileName)
// NOTE: image is not unloaded, it must be done manually
Texture2D LoadTextureFromImage(Image image)
{
- Texture2D texture;
-
- // Init texture to default values
- texture.id = 0;
- texture.width = 0;
- texture.height = 0;
- texture.mipmaps = 0;
- texture.format = 0;
+ Texture2D texture = { 0 };
texture.id = rlglLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
@@ -322,6 +384,8 @@ Texture2D LoadTextureFromImage(Image image)
texture.height = image.height;
texture.mipmaps = image.mipmaps;
texture.format = image.format;
+
+ TraceLog(DEBUG, "[TEX ID %i] Parameters: %ix%i, %i mips, format %i", texture.id, texture.width, texture.height, texture.mipmaps, texture.format);
return texture;
}
@@ -451,9 +515,8 @@ Color *GetImageData(Image image)
// NOTE: Compressed texture formats not supported
Image GetTextureData(Texture2D texture)
{
- Image image;
- image.data = NULL;
-
+ Image image = { 0 };
+
if (texture.format < 8)
{
image.data = rlglReadTexturePixels(texture);
@@ -463,12 +526,14 @@ Image GetTextureData(Texture2D texture)
image.width = texture.width;
image.height = texture.height;
image.mipmaps = 1;
-#if defined(GRAPHICS_API_OPENGL_ES2)
- // NOTE: Data retrieved on OpenGL ES 2.0 comes as RGB (from framebuffer)
- image.format = UNCOMPRESSED_R8G8B8A8;
-#else
- image.format = texture.format;
-#endif
+
+ if (rlGetVersion() == OPENGL_ES_20)
+ {
+ // NOTE: Data retrieved on OpenGL ES 2.0 comes as RGBA (from framebuffer)
+ image.format = UNCOMPRESSED_R8G8B8A8;
+ }
+ else image.format = texture.format;
+
TraceLog(INFO, "Texture pixel data obtained successfully");
}
else TraceLog(WARNING, "Texture pixel data could not be obtained");
@@ -664,115 +729,6 @@ void ImageAlphaMask(Image *image, Image alphaMask)
}
}
-// Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-// 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 >= COMPRESSED_DXT1_RGB)
- {
- TraceLog(WARNING, "Compressed data formats can not be dithered");
- return;
- }
-
- if ((rBpp+gBpp+bBpp+aBpp) > 16)
- {
- TraceLog(WARNING, "Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported", (rBpp+gBpp+bBpp+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;
- else if ((rBpp == 4) && (gBpp == 4) && (bBpp == 4) && (aBpp == 4)) image->format = UNCOMPRESSED_R4G4B4A4;
- else
- {
- image->format = 0;
- TraceLog(WARNING, "Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i)", (rBpp+gBpp+bBpp+aBpp), rBpp, gBpp, bBpp, 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 rError, gError, bError;
- unsigned short rPixel, gPixel, bPixel, aPixel; // Used for 16bit pixel composition
-
- #define MIN(a,b) (((a)<(b))?(a):(b))
-
- for (int y = 0; y < image->height; y++)
- {
- 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
- newPixel.b = oldPixel.b >> (8 - bBpp); // B bits
- newPixel.a = oldPixel.a >> (8 - aBpp); // A bits (not used on dithering)
-
- // NOTE: Error must be computed between new and old pixel but using same number of bits!
- // We want to know how much color precision we have lost...
- rError = (int)oldPixel.r - (int)(newPixel.r << (8 - rBpp));
- gError = (int)oldPixel.g - (int)(newPixel.g << (8 - gBpp));
- bError = (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
- if (x < (image->width - 1))
- {
- pixels[y*image->width + x+1].r = MIN((int)pixels[y*image->width + x+1].r + (int)((float)rError*7.0f/16), 0xff);
- pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)gError*7.0f/16), 0xff);
- pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)bError*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)rError*3.0f/16), 0xff);
- pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)gError*3.0f/16), 0xff);
- pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)bError*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)rError*5.0f/16), 0xff);
- pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)gError*5.0f/16), 0xff);
- pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)bError*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)rError*1.0f/16), 0xff);
- pixels[(y+1)*image->width + x+1].g = MIN((int)pixels[(y+1)*image->width + x+1].g + (int)((float)gError*1.0f/16), 0xff);
- pixels[(y+1)*image->width + x+1].b = MIN((int)pixels[(y+1)*image->width + x+1].b + (int)((float)bError*1.0f/16), 0xff);
- }
-
- rPixel = (unsigned short)newPixel.r;
- gPixel = (unsigned short)newPixel.g;
- bPixel = (unsigned short)newPixel.b;
- aPixel = (unsigned short)newPixel.a;
-
- ((unsigned short *)image->data)[y*image->width + x] = (rPixel << (gBpp + bBpp + aBpp)) | (gPixel << (bBpp + aBpp)) | (bPixel << aBpp) | aPixel;
- }
- }
-
- free(pixels);
- }
-}
-
// Convert image to POT (power-of-two)
// NOTE: It could be useful on OpenGL ES 2.0 (RPI, HTML5)
void ImageToPOT(Image *image, Color fillColor)
@@ -818,6 +774,7 @@ void ImageToPOT(Image *image, Color fillColor)
}
}
+#if defined(SUPPORT_IMAGE_MANIPULATION)
// Copy an image to a new image
Image ImageCopy(Image image)
{
@@ -834,6 +791,7 @@ Image ImageCopy(Image image)
case UNCOMPRESSED_R4G4B4A4: byteSize *= 2; break; // 16 bpp (2 bytes)
case UNCOMPRESSED_R8G8B8: byteSize *= 3; break; // 24 bpp (3 bytes)
case UNCOMPRESSED_R8G8B8A8: byteSize *= 4; break; // 32 bpp (4 bytes)
+ case UNCOMPRESSED_R32G32B32: byteSize *= 12; break; // 4 byte per channel (12 bytes)
case COMPRESSED_DXT3_RGBA:
case COMPRESSED_DXT5_RGBA:
case COMPRESSED_ETC2_EAC_RGBA:
@@ -1203,6 +1161,115 @@ void ImageFlipHorizontal(Image *image)
image->data = processed.data;
}
+// Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
+// 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 >= COMPRESSED_DXT1_RGB)
+ {
+ TraceLog(WARNING, "Compressed data formats can not be dithered");
+ return;
+ }
+
+ if ((rBpp+gBpp+bBpp+aBpp) > 16)
+ {
+ TraceLog(WARNING, "Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported", (rBpp+gBpp+bBpp+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;
+ else if ((rBpp == 4) && (gBpp == 4) && (bBpp == 4) && (aBpp == 4)) image->format = UNCOMPRESSED_R4G4B4A4;
+ else
+ {
+ image->format = 0;
+ TraceLog(WARNING, "Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i)", (rBpp+gBpp+bBpp+aBpp), rBpp, gBpp, bBpp, 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 rError, gError, bError;
+ unsigned short rPixel, gPixel, bPixel, aPixel; // Used for 16bit pixel composition
+
+ #define MIN(a,b) (((a)<(b))?(a):(b))
+
+ for (int y = 0; y < image->height; y++)
+ {
+ 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
+ newPixel.b = oldPixel.b >> (8 - bBpp); // B bits
+ newPixel.a = oldPixel.a >> (8 - aBpp); // A bits (not used on dithering)
+
+ // NOTE: Error must be computed between new and old pixel but using same number of bits!
+ // We want to know how much color precision we have lost...
+ rError = (int)oldPixel.r - (int)(newPixel.r << (8 - rBpp));
+ gError = (int)oldPixel.g - (int)(newPixel.g << (8 - gBpp));
+ bError = (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
+ if (x < (image->width - 1))
+ {
+ pixels[y*image->width + x+1].r = MIN((int)pixels[y*image->width + x+1].r + (int)((float)rError*7.0f/16), 0xff);
+ pixels[y*image->width + x+1].g = MIN((int)pixels[y*image->width + x+1].g + (int)((float)gError*7.0f/16), 0xff);
+ pixels[y*image->width + x+1].b = MIN((int)pixels[y*image->width + x+1].b + (int)((float)bError*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)rError*3.0f/16), 0xff);
+ pixels[(y+1)*image->width + x-1].g = MIN((int)pixels[(y+1)*image->width + x-1].g + (int)((float)gError*3.0f/16), 0xff);
+ pixels[(y+1)*image->width + x-1].b = MIN((int)pixels[(y+1)*image->width + x-1].b + (int)((float)bError*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)rError*5.0f/16), 0xff);
+ pixels[(y+1)*image->width + x].g = MIN((int)pixels[(y+1)*image->width + x].g + (int)((float)gError*5.0f/16), 0xff);
+ pixels[(y+1)*image->width + x].b = MIN((int)pixels[(y+1)*image->width + x].b + (int)((float)bError*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)rError*1.0f/16), 0xff);
+ pixels[(y+1)*image->width + x+1].g = MIN((int)pixels[(y+1)*image->width + x+1].g + (int)((float)gError*1.0f/16), 0xff);
+ pixels[(y+1)*image->width + x+1].b = MIN((int)pixels[(y+1)*image->width + x+1].b + (int)((float)bError*1.0f/16), 0xff);
+ }
+
+ rPixel = (unsigned short)newPixel.r;
+ gPixel = (unsigned short)newPixel.g;
+ bPixel = (unsigned short)newPixel.b;
+ aPixel = (unsigned short)newPixel.a;
+
+ ((unsigned short *)image->data)[y*image->width + x] = (rPixel << (gBpp + bBpp + aBpp)) | (gPixel << (bBpp + aBpp)) | (bPixel << aBpp) | aPixel;
+ }
+ }
+
+ free(pixels);
+ }
+}
+
// Modify image color: tint
void ImageColorTint(Image *image, Color color)
{
@@ -1359,6 +1426,7 @@ void ImageColorBrightness(Image *image, int brightness)
image->data = processed.data;
}
+#endif // SUPPORT_IMAGE_MANIPULATION
// Generate GPU mipmaps for a texture
void GenTextureMipmaps(Texture2D *texture)
@@ -1547,6 +1615,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
// Module specific Functions Definition
//----------------------------------------------------------------------------------
+#if defined(SUPPORT_FILEFORMAT_DDS)
// Loading DDS image data (compressed or uncompressed)
static Image LoadDDS(const char *fileName)
{
@@ -1744,7 +1813,9 @@ static Image LoadDDS(const char *fileName)
return image;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_PKM)
// Loading PKM image data (ETC1/ETC2 compression)
// NOTE: KTX is the standard Khronos Group compression format (ETC1/ETC2, mipmaps)
// PKM is a much simpler file format used mainly to contain a single ETC1/ETC2 compressed image (no mipmaps)
@@ -1836,7 +1907,9 @@ static Image LoadPKM(const char *fileName)
return image;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_KTX)
// Load KTX compressed image data (ETC1/ETC2 compression)
static Image LoadKTX(const char *fileName)
{
@@ -1929,7 +2002,9 @@ static Image LoadKTX(const char *fileName)
return image;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_PVR)
// Loading PVR image data (uncompressed or PVRT compression)
// NOTE: PVR v2 not supported, use PVR v3 instead
static Image LoadPVR(const char *fileName)
@@ -2087,7 +2162,9 @@ static Image LoadPVR(const char *fileName)
return image;
}
+#endif
+#if defined(SUPPORT_FILEFORMAT_ASTC)
// Load ASTC compressed image data (ASTC compression)
static Image LoadASTC(const char *fileName)
{
@@ -2170,3 +2247,4 @@ static Image LoadASTC(const char *fileName)
return image;
}
+#endif \ No newline at end of file
diff --git a/src/utils.c b/src/utils.c
index 9a2a723a..c86c9c82 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -4,22 +4,28 @@
*
* CONFIGURATION:
*
-* #define SUPPORT_SAVE_PNG
-* Enable saving PNG fileformat
+* #define SUPPORT_SAVE_PNG (defined by default)
+* Support saving image data as PNG fileformat
* NOTE: Requires stb_image_write library
*
* #define SUPPORT_SAVE_BMP
+* Support saving image data as BMP fileformat
+* NOTE: Requires stb_image_write library
+*
+* #define SUPPORT_TRACELOG
+* Show TraceLog() output messages
+* NOTE: By default DEBUG traces not shown
*
-* #define DO_NOT_TRACE_DEBUG_MSGS
-* Avoid showing DEBUG TraceLog() messages
+* #define SUPPORT_TRACELOG_DEBUG
+* Show TraceLog() DEBUG messages
*
* DEPENDENCIES:
-* stb_image_write - PNG writting functions
+* stb_image_write - BMP/PNG writting functions
*
*
* LICENSE: zlib/libpng
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -38,6 +44,9 @@
*
**********************************************************************************************/
+#define SUPPORT_TRACELOG // Output tracelog messages
+//#define SUPPORT_TRACELOG_DEBUG // Avoid DEBUG messages tracing
+
#include "utils.h"
#if defined(PLATFORM_ANDROID)
@@ -59,9 +68,6 @@
#define RRES_IMPLEMENTATION
#include "rres.h"
-//#define NO_TRACELOG // Avoid TraceLog() output (any type)
-#define DO_NOT_TRACE_DEBUG_MSGS // Avoid DEBUG messages tracing
-
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
@@ -82,15 +88,16 @@ static int android_close(void *cookie);
//----------------------------------------------------------------------------------
// Module Functions Definition - Utilities
//----------------------------------------------------------------------------------
-// Outputs a trace log message
+
+// Output trace log messages
void TraceLog(int msgType, const char *text, ...)
{
-#if !defined(NO_TRACELOG)
+#if defined(SUPPORT_TRACELOG)
static char buffer[128];
- int traceDebugMsgs = 1;
+ int traceDebugMsgs = 0;
-#ifdef DO_NOT_TRACE_DEBUG_MSGS
- traceDebugMsgs = 0;
+#if defined(SUPPORT_TRACELOG_DEBUG)
+ traceDebugMsgs = 1;
#endif
switch(msgType)
@@ -125,22 +132,37 @@ void TraceLog(int msgType, const char *text, ...)
if (msgType == ERROR) exit(1); // If ERROR message, exit program
-#endif // NO_TRACELOG
+#endif // SUPPORT_TRACELOG
}
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+
+#if defined(SUPPORT_SAVE_BMP)
// Creates a BMP image file from an array of pixel data
void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize)
{
stbi_write_bmp(fileName, width, height, compSize, imgData);
}
+#endif
+#if defined(SUPPORT_SAVE_PNG)
// Creates a PNG image file from an array of pixel data
void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize)
{
stbi_write_png(fileName, width, height, compSize, imgData, width*compSize);
}
#endif
+#endif
+
+// Keep track of memory allocated
+// NOTE: mallocType defines the type of data allocated
+/*
+void RecordMalloc(int mallocType, int mallocSize, const char *msg)
+{
+ // TODO: Investigate how to record memory allocation data...
+ // Maybe creating my own malloc function...
+}
+*/
#if defined(PLATFORM_ANDROID)
// Initialize asset manager from android app
@@ -162,24 +184,6 @@ FILE *android_fopen(const char *fileName, const char *mode)
}
#endif
-// Keep track of memory allocated
-// NOTE: mallocType defines the type of data allocated
-/*
-void RecordMalloc(int mallocType, int mallocSize, const char *msg)
-{
- // TODO: Investigate how to record memory allocation data...
- // Maybe creating my own malloc function...
-}
-*/
-
-// Get the extension for a filename
-const char *GetExtension(const char *fileName)
-{
- const char *dot = strrchr(fileName, '.');
- if (!dot || dot == fileName) return "";
- return (dot + 1);
-}
-
//----------------------------------------------------------------------------------
// Module specific Functions Definition
//----------------------------------------------------------------------------------
diff --git a/src/utils.h b/src/utils.h
index 3ffd025c..64592c73 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,10 +1,11 @@
/**********************************************************************************************
*
-* raylib.utils
+* raylib.utils - Some common utility functions
*
-* Some utility functions
*
-* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5)
+* LICENSE: zlib/libpng
+*
+* Copyright (c) 2014-2017 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
@@ -33,6 +34,8 @@
#include "rres.h"
+#define SUPPORT_SAVE_PNG
+
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
@@ -43,8 +46,6 @@
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
-typedef enum { INFO = 0, ERROR, WARNING, DEBUG, OTHER } TraceLogType;
-
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
@@ -57,17 +58,18 @@ extern "C" { // Prevents name mangling of functions
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
-void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message
-const char *GetExtension(const char *fileName); // Returns extension of a filename
-
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
+#if defined(SUPPORT_SAVE_BMP)
void SaveBMP(const char *fileName, unsigned char *imgData, int width, int height, int compSize);
+#endif
+#if defined(SUPPORT_SAVE_PNG)
void SavePNG(const char *fileName, unsigned char *imgData, int width, int height, int compSize);
#endif
+#endif
#if defined(PLATFORM_ANDROID)
void InitAssetManager(AAssetManager *manager); // Initialize asset manager from android app
-FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen()
+FILE *android_fopen(const char *fileName, const char *mode); // Replacement for fopen()
#endif
#ifdef __cplusplus