Merge branch 'upstream-merge'
This commit is contained in:
commit
109523548e
14
BINDINGS.md
14
BINDINGS.md
|
|
@ -21,17 +21,19 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
||||||
| nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib |
|
| nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib |
|
||||||
| NimraylibNow! | 4.0 | [Nim](https://nim-lang.org/) | MIT | https://github.com/greenfork/nimraylib_now |
|
| NimraylibNow! | 4.0 | [Nim](https://nim-lang.org/) | MIT | https://github.com/greenfork/nimraylib_now |
|
||||||
| raylib-Forever | auto | [Nim](https://nim-lang.org/) | ? | https://github.com/Guevara-chan/Raylib-Forever |
|
| raylib-Forever | auto | [Nim](https://nim-lang.org/) | ? | https://github.com/Guevara-chan/Raylib-Forever |
|
||||||
|
| naylib | auto | [Nim](https://nim-lang.org/) | MIT | https://github.com/planetis-m/naylib |
|
||||||
| Ray4Laz | **4.0** | [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))| Zlib | https://github.com/GuvaCode/Ray4Laz |
|
| Ray4Laz | **4.0** | [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))| Zlib | https://github.com/GuvaCode/Ray4Laz |
|
||||||
| pyraylib | 3.7 | [Python](https://www.python.org/) | Zlib | https://github.com/Ho011/pyraylib |
|
| pyraylib | 3.7 | [Python](https://www.python.org/) | Zlib | https://github.com/Ho011/pyraylib |
|
||||||
| raylib-python-cffi | **4.0** | [Python](https://www.python.org/) | EPL-2.0 | https://github.com/electronstudio/raylib-python-cffi |
|
| raylib-python-cffi | **4.0** | [Python](https://www.python.org/) | EPL-2.0 | https://github.com/electronstudio/raylib-python-cffi |
|
||||||
| jaylib | **4.0** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3 | https://github.com/electronstudio/jaylib/ |
|
| jaylib | **4.0** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | GPLv3 | https://github.com/electronstudio/jaylib/ |
|
||||||
| raylib-j | **4.0** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J |
|
| raylib-j | **4.0** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J |
|
||||||
| node-raylib | 3.5 | [Node.js](https://nodejs.org/en/) | Zlib | https://github.com/RobLoach/node-raylib |
|
| raylib.jl | **4.0** | [Julia](https://julialang.org/) | Zlib | https://github.com/irishgreencitrus/raylib.jl |
|
||||||
|
| node-raylib | **4.0** | [Node.js](https://nodejs.org/en/) | Zlib | https://github.com/RobLoach/node-raylib |
|
||||||
| raylib-php | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/joseph-montanez/raylib-php |
|
| raylib-php | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/joseph-montanez/raylib-php |
|
||||||
| raylib-phpcpp | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/oraoto/raylib-phpcpp |
|
| raylib-phpcpp | 3.5 | [PHP](https://en.wikipedia.org/wiki/PHP) | Zlib | https://github.com/oraoto/raylib-phpcpp |
|
||||||
| raylib-factor | 3.5 | [Factor](https://factorcode.org/) | MIT | https://github.com/ArnautDaniel/raylib-factor |
|
| raylib-factor | **4.0** | [Factor](https://factorcode.org/) | BSD | https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor |
|
||||||
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | MIT | https://github.com/ArnautDaniel/gforth-raylib |
|
| gforth-raylib | 3.5 | [Gforth](https://gforth.org/) | MIT | https://github.com/ArnautDaniel/gforth-raylib |
|
||||||
| hxRaylib | 4.0 | [Haxe](https://haxe.org/) | Zlib | https://github.com/ForeignSasquatch/hxRaylib |
|
| raylib-hx | 4.0 | [Haxe](https://haxe.org/) | Zlib | https://github.com/foreignsasquatch/raylib-hx |
|
||||||
| raylib-wren | **4.0** | [Wren](http://wren.io/) | ISC | https://github.com/TSnake41/raylib-wren |
|
| raylib-wren | **4.0** | [Wren](http://wren.io/) | ISC | https://github.com/TSnake41/raylib-wren |
|
||||||
| raylib_odin_bindings | 4.0-dev | [Odin](https://odin-lang.org/) | MIT | https://github.com/Deathbat2190/raylib_odin_bindings |
|
| raylib_odin_bindings | 4.0-dev | [Odin](https://odin-lang.org/) | MIT | https://github.com/Deathbat2190/raylib_odin_bindings |
|
||||||
| raylib-odin | **4.0** | [Odin](https://odin-lang.org/) | BSD-3Clause | https://github.com/odin-lang/Odin/tree/master/vendor/raylib |
|
| raylib-odin | **4.0** | [Odin](https://odin-lang.org/) | BSD-3Clause | https://github.com/odin-lang/Odin/tree/master/vendor/raylib |
|
||||||
|
|
@ -48,6 +50,9 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
||||||
| dart-raylib | **4.0** | [Dart](https://dart.dev/) | MIT | https://gitlab.com/wolfenrain/dart-raylib |
|
| dart-raylib | **4.0** | [Dart](https://dart.dev/) | MIT | https://gitlab.com/wolfenrain/dart-raylib |
|
||||||
| raylib-scopes | auto | [Scopes](http://scopes.rocks) | MIT | https://github.com/salotz/raylib-scopes |
|
| raylib-scopes | auto | [Scopes](http://scopes.rocks) | MIT | https://github.com/salotz/raylib-scopes |
|
||||||
| raylib-smallBasic | 4.1-dev | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib |
|
| raylib-smallBasic | 4.1-dev | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib |
|
||||||
|
| raylib-zig | **4.0** | [Zig](https://ziglang.org/) | MIT | https://github.com/Not-Nik/raylib-zig |
|
||||||
|
| raylib.zig | **4.1-dev** | [Zig](https://ziglang.org/) | MIT | https://github.com/ryupold/raylib.zig |
|
||||||
|
| racket-raylib | **4.0** | [Racket](https://racket-lang.org/) | MIT/Apache-2.0 | https://github.com/eutro/racket-raylib |
|
||||||
|
|
||||||
### Utility Wrapers
|
### Utility Wrapers
|
||||||
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's pardigm.
|
These are utility wrappers for specific languages, they are not required to use raylib in the language but may adapt the raylib API to be more inline with the language's pardigm.
|
||||||
|
|
@ -105,8 +110,7 @@ These are older raylib bindings that are more than 2 versions old or have not be
|
||||||
| Euraylib | 3.0 | [Euphoria](https://openeuphoria.org/) | https://github.com/gAndy50/Euraylib |
|
| Euraylib | 3.0 | [Euphoria](https://openeuphoria.org/) | https://github.com/gAndy50/Euraylib |
|
||||||
| raylib-odin | 3.0 | [Odin](https://odin-lang.org/) | https://github.com/kevinw/raylib-odin |
|
| raylib-odin | 3.0 | [Odin](https://odin-lang.org/) | https://github.com/kevinw/raylib-odin |
|
||||||
| vraylib | 3.5 | [V](https://vlang.io/) | https://github.com/waotzi/vraylib |
|
| vraylib | 3.5 | [V](https://vlang.io/) | https://github.com/waotzi/vraylib |
|
||||||
| raylib-zig | 3.0 | [Zig](https://ziglang.org/) | https://github.com/Not-Nik/raylib-zig |
|
| raylib-jai | 3.1-dev | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | https://github.com/kujukuju/raylib-jai |
|
||||||
| raylib-jai | 3.1-dev | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | https://github.com/kevinw/raylib-jai |
|
|
||||||
| ray.zig | 2.5 | [Zig](https://ziglang.org/) | https://github.com/BitPuffin/zig-raylib-experiments |
|
| ray.zig | 2.5 | [Zig](https://ziglang.org/) | https://github.com/BitPuffin/zig-raylib-experiments |
|
||||||
| raylib-Ada | 3.0 | [Ada](https://www.adacore.com/about-ada) | https://github.com/mimo/raylib-Ada |
|
| raylib-Ada | 3.0 | [Ada](https://www.adacore.com/about-ada) | https://github.com/mimo/raylib-Ada |
|
||||||
| jaylib | 3.0 | [Janet](https://janet-lang.org/) | https://github.com/janet-lang/jaylib |
|
| jaylib | 3.0 | [Janet](https://janet-lang.org/) | https://github.com/janet-lang/jaylib |
|
||||||
|
|
|
||||||
19
README.md
19
README.md
|
|
@ -4,7 +4,7 @@ This is the repository of the Nintendo Switch port of the raylib using LibNX run
|
||||||
|
|
||||||
Please, follow the wiki page in order to install and use it:
|
Please, follow the wiki page in order to install and use it:
|
||||||
|
|
||||||
- [Working on Switch](https://github.com/luizpestana/raylib-nx/wiki/Working-on-Switch)
|
- [Working on Switch](https://github.com/lucaskyer/raylib-nx/wiki/Working-on-Switch)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -22,16 +22,19 @@ Ready to learn? Jump to [code examples!](https://www.raylib.com/examples.html)
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
[](https://github.com/raysan5/raylib/graphs/contributors)
|
[](https://github.com/raysan5/raylib/graphs/contributors)
|
||||||
[](https://github.com/raysan5/raylib/releases)
|
[](https://github.com/raysan5/raylib/releases)
|
||||||
[](https://repology.org/project/raylib/versions)
|
[](https://github.com/raysan5/raylib/stargazers)
|
||||||
[](https://github.com/raysan5/raylib/commits/master)
|
[](https://github.com/raysan5/raylib/commits/master)
|
||||||
|
[](https://repology.org/project/raylib/versions)
|
||||||
[](LICENSE)
|
[](LICENSE)
|
||||||
|
|
||||||
[](https://discord.gg/raylib)
|
[](https://discord.gg/raylib)
|
||||||
[](https://github.com/raysan5/raylib/stargazers)
|
[](https://www.reddit.com/r/raylib/)
|
||||||
[](https://twitter.com/raysan5)
|
[](https://www.youtube.com/c/raylib)
|
||||||
[](https://www.reddit.com/r/raylib/)
|
[](https://www.twitch.tv/raysan5)
|
||||||
|
[](https://twitter.com/raysan5)
|
||||||
|
|
||||||
|
|
||||||
[](https://github.com/raysan5/raylib/actions?query=workflow%3AWindows)
|
[](https://github.com/raysan5/raylib/actions?query=workflow%3AWindows)
|
||||||
[](https://github.com/raysan5/raylib/actions?query=workflow%3ALinux)
|
[](https://github.com/raysan5/raylib/actions?query=workflow%3ALinux)
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ The following people are currently [**sponsoring raylib**](https://github.com/sp
|
||||||
- Matthew Owens ([@MatthewOwens](https://github.com/MatthewOwens))
|
- Matthew Owens ([@MatthewOwens](https://github.com/MatthewOwens))
|
||||||
- Tim Eilers ([@eilerstim](https://github.com/eilerstim))
|
- Tim Eilers ([@eilerstim](https://github.com/eilerstim))
|
||||||
- Laurentino Luna ([@catmanl](https://github.com/catmanl))
|
- Laurentino Luna ([@catmanl](https://github.com/catmanl))
|
||||||
|
- ZimonIsHim ([@ZimonIsHim](https://github.com/ZimonIsHim))
|
||||||
|
|
||||||
### Past raylib GitHub Sponsors
|
### Past raylib GitHub Sponsors
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ elseif (${PLATFORM} MATCHES "Android")
|
||||||
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
set(raylib_sources "${raylib_sources} ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c")
|
list(APPEND raylib_sources ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
|
||||||
add_definitions(-DANDROID -D__ANDROID_API__=21)
|
add_definitions(-DANDROID -D__ANDROID_API__=21)
|
||||||
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
|
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup")
|
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libatomic.a -Wl,--build-id -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings -u ANativeActivity_onCreate -Wl,-undefined,dynamic_lookup")
|
||||||
|
|
@ -87,7 +87,9 @@ endif ()
|
||||||
|
|
||||||
if (${OPENGL_VERSION})
|
if (${OPENGL_VERSION})
|
||||||
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
|
set(${SUGGESTED_GRAPHICS} "${GRAPHICS}")
|
||||||
if (${OPENGL_VERSION} MATCHES "3.3")
|
if (${OPENGL_VERSION} MATCHES "4.3")
|
||||||
|
set(GRAPHICS "GRAPHICS_API_OPENGL_43")
|
||||||
|
elseif (${OPENGL_VERSION} MATCHES "3.3")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_33")
|
||||||
elseif (${OPENGL_VERSION} MATCHES "2.1")
|
elseif (${OPENGL_VERSION} MATCHES "2.1")
|
||||||
set(GRAPHICS "GRAPHICS_API_OPENGL_21")
|
set(GRAPHICS "GRAPHICS_API_OPENGL_21")
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,7 @@ INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external -I$(RAYLI
|
||||||
|
|
||||||
# Define additional directories containing required header files
|
# Define additional directories containing required header files
|
||||||
ifeq ($(PLATFORM),PLATFORM_NX)
|
ifeq ($(PLATFORM),PLATFORM_NX)
|
||||||
|
INCLUDE_PATHS += -I$(RAYLIB_PATH)/src/switch-nx
|
||||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
|
||||||
CFLAGS += -ffunction-sections $(ARCH) $(foreach dir,$(LIBDIRS),-I$(dir)/include) -D__SWITCH__
|
CFLAGS += -ffunction-sections $(ARCH) $(foreach dir,$(LIBDIRS),-I$(dir)/include) -D__SWITCH__
|
||||||
|
|
@ -379,7 +380,7 @@ endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||||
# Libraries for Raspberry Pi compiling
|
# Libraries for Raspberry Pi compiling
|
||||||
# NOTE: Required packages: libasound2-dev (ALSA)
|
# NOTE: Required packages: libasound2-dev (ALSA)
|
||||||
LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
|
LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl -latomic
|
||||||
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
|
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
|
||||||
LDLIBS += -lvchiq_arm -lvcos
|
LDLIBS += -lvchiq_arm -lvcos
|
||||||
endif
|
endif
|
||||||
|
|
@ -387,7 +388,7 @@ endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_DRM)
|
ifeq ($(PLATFORM),PLATFORM_DRM)
|
||||||
# Libraries for DRM compiling
|
# Libraries for DRM compiling
|
||||||
# NOTE: Required packages: libasound2-dev (ALSA)
|
# NOTE: Required packages: libasound2-dev (ALSA)
|
||||||
LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl
|
LDLIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lgbm -ldrm -ldl -latomic
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||||
# Libraries for web (HTML5) compiling
|
# Libraries for web (HTML5) compiling
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,49 @@
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#include <stdlib.h> // Required for: NULL
|
||||||
|
|
||||||
|
// Audio effect: lowpass filter
|
||||||
|
static void AudioProcessEffectLPF(void *buffer, unsigned int frames)
|
||||||
|
{
|
||||||
|
static float low[2] = { 0.0f, 0.0f };
|
||||||
|
static const float cutoff = 70.0f / 44100.0f; // 70 Hz lowpass filter
|
||||||
|
const float k = cutoff / (cutoff + 0.1591549431f); // RC filter formula
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < frames*2; i += 2)
|
||||||
|
{
|
||||||
|
float l = ((float *)buffer)[i], r = ((float *)buffer)[i + 1];
|
||||||
|
low[0] += k * (l - low[0]);
|
||||||
|
low[1] += k * (r - low[1]);
|
||||||
|
((float *)buffer)[i] = low[0];
|
||||||
|
((float *)buffer)[i + 1] = low[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float *delayBuffer = NULL;
|
||||||
|
static unsigned int delayBufferSize = 0;
|
||||||
|
static unsigned int delayReadIndex = 2;
|
||||||
|
static unsigned int delayWriteIndex = 0;
|
||||||
|
|
||||||
|
// Audio effect: delay
|
||||||
|
static void AudioProcessEffectDelay(void *buffer, unsigned int frames)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < frames*2; i += 2)
|
||||||
|
{
|
||||||
|
float leftDelay = delayBuffer[delayReadIndex++]; // ERROR: Reading buffer -> WHY??? Maybe thread related???
|
||||||
|
float rightDelay = delayBuffer[delayReadIndex++];
|
||||||
|
|
||||||
|
if (delayReadIndex == delayBufferSize) delayReadIndex = 0;
|
||||||
|
|
||||||
|
((float *)buffer)[i] = 0.5f*((float *)buffer)[i] + 0.5f*leftDelay;
|
||||||
|
((float *)buffer)[i + 1] = 0.5f*((float *)buffer)[i + 1] + 0.5f*rightDelay;
|
||||||
|
|
||||||
|
delayBuffer[delayWriteIndex++] = ((float *)buffer)[i];
|
||||||
|
delayBuffer[delayWriteIndex++] = ((float *)buffer)[i + 1];
|
||||||
|
if (delayWriteIndex == delayBufferSize) delayWriteIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
|
|
@ -24,11 +67,18 @@ int main(void)
|
||||||
|
|
||||||
Music music = LoadMusicStream("resources/country.mp3");
|
Music music = LoadMusicStream("resources/country.mp3");
|
||||||
|
|
||||||
|
// Allocate buffer for the delay effect
|
||||||
|
delayBufferSize = 48000 * 2;
|
||||||
|
delayBuffer = (float *)RL_CALLOC(delayBufferSize, sizeof(float)); // 1 second delay (device sampleRate*channels)
|
||||||
|
|
||||||
PlayMusicStream(music);
|
PlayMusicStream(music);
|
||||||
|
|
||||||
float timePlayed = 0.0f;
|
float timePlayed = 0.0f;
|
||||||
bool pause = false;
|
bool pause = false;
|
||||||
|
|
||||||
|
bool hasFilter = true;
|
||||||
|
bool hasDelay = true;
|
||||||
|
|
||||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -55,6 +105,22 @@ int main(void)
|
||||||
else ResumeMusicStream(music);
|
else ResumeMusicStream(music);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add/Remove effect: lowpass filter
|
||||||
|
if (IsKeyPressed(KEY_F))
|
||||||
|
{
|
||||||
|
hasFilter = !hasFilter;
|
||||||
|
if (hasFilter) AttachAudioStreamProcessor(music.stream, AudioProcessEffectLPF);
|
||||||
|
else DetachAudioStreamProcessor(music.stream, AudioProcessEffectLPF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add/Remove effect: delay
|
||||||
|
if (IsKeyPressed(KEY_D))
|
||||||
|
{
|
||||||
|
hasDelay = !hasDelay;
|
||||||
|
if (hasDelay) AttachAudioStreamProcessor(music.stream, AudioProcessEffectDelay);
|
||||||
|
else DetachAudioStreamProcessor(music.stream, AudioProcessEffectDelay);
|
||||||
|
}
|
||||||
|
|
||||||
// Get timePlayed scaled to bar dimensions (400 pixels)
|
// Get timePlayed scaled to bar dimensions (400 pixels)
|
||||||
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*400;
|
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*400;
|
||||||
|
|
||||||
|
|
@ -86,6 +152,8 @@ int main(void)
|
||||||
|
|
||||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||||
|
|
||||||
|
RL_FREE(delayBuffer); // Free delay buffer
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,36 @@
|
||||||
#define MAX_SAMPLES 512
|
#define MAX_SAMPLES 512
|
||||||
#define MAX_SAMPLES_PER_UPDATE 4096
|
#define MAX_SAMPLES_PER_UPDATE 4096
|
||||||
|
|
||||||
|
// Cycles per second (hz)
|
||||||
|
float frequency = 440.0f;
|
||||||
|
|
||||||
|
// Audio frequency, for smoothing
|
||||||
|
float audioFrequency = 440.0f;
|
||||||
|
|
||||||
|
// Previous value, used to test if sine needs to be rewritten, and to smoothly modulate frequency
|
||||||
|
float oldFrequency = 1.0f;
|
||||||
|
|
||||||
|
// Index for audio rendering
|
||||||
|
float sineIdx = 0.0f;
|
||||||
|
|
||||||
|
// Audio input processing callback
|
||||||
|
void AudioInputCallback(void *buffer, unsigned int frames)
|
||||||
|
{
|
||||||
|
audioFrequency = frequency + (audioFrequency - frequency)*0.95f;
|
||||||
|
audioFrequency += 1.0f;
|
||||||
|
audioFrequency -= 1.0f;
|
||||||
|
float incr = audioFrequency/44100.0f;
|
||||||
|
short *d = (short *)buffer;
|
||||||
|
|
||||||
|
for (int i = 0; i < frames; i++)
|
||||||
|
{
|
||||||
|
d[i] = (short)(32000.0f*sinf(2*PI*sineIdx));
|
||||||
|
sineIdx += incr;
|
||||||
|
if (sineIdx > 1.0f) sineIdx -= 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
|
|
@ -33,9 +63,11 @@ int main(void)
|
||||||
|
|
||||||
SetAudioStreamBufferSizeDefault(MAX_SAMPLES_PER_UPDATE);
|
SetAudioStreamBufferSizeDefault(MAX_SAMPLES_PER_UPDATE);
|
||||||
|
|
||||||
// Init raw audio stream (sample rate: 22050, sample size: 16bit-short, channels: 1-mono)
|
// Init raw audio stream (sample rate: 44100, sample size: 16bit-short, channels: 1-mono)
|
||||||
AudioStream stream = LoadAudioStream(44100, 16, 1);
|
AudioStream stream = LoadAudioStream(44100, 16, 1);
|
||||||
|
|
||||||
|
SetAudioStreamCallback(stream, AudioInputCallback);
|
||||||
|
|
||||||
// Buffer for the single cycle waveform we are synthesizing
|
// Buffer for the single cycle waveform we are synthesizing
|
||||||
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
|
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
|
||||||
|
|
||||||
|
|
@ -47,6 +79,7 @@ int main(void)
|
||||||
// Position read in to determine next frequency
|
// Position read in to determine next frequency
|
||||||
Vector2 mousePosition = { -100.0f, -100.0f };
|
Vector2 mousePosition = { -100.0f, -100.0f };
|
||||||
|
|
||||||
|
/*
|
||||||
// Cycles per second (hz)
|
// Cycles per second (hz)
|
||||||
float frequency = 440.0f;
|
float frequency = 440.0f;
|
||||||
|
|
||||||
|
|
@ -55,6 +88,7 @@ int main(void)
|
||||||
|
|
||||||
// Cursor to read and copy the samples of the sine wave buffer
|
// Cursor to read and copy the samples of the sine wave buffer
|
||||||
int readCursor = 0;
|
int readCursor = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
// Computed size in samples of the sine wave
|
// Computed size in samples of the sine wave
|
||||||
int waveLength = 1;
|
int waveLength = 1;
|
||||||
|
|
@ -82,7 +116,7 @@ int main(void)
|
||||||
SetAudioStreamPan(stream, pan);
|
SetAudioStreamPan(stream, pan);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite the sine wave.
|
// Rewrite the sine wave
|
||||||
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
|
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
|
||||||
if (frequency != oldFrequency)
|
if (frequency != oldFrequency)
|
||||||
{
|
{
|
||||||
|
|
@ -92,17 +126,18 @@ int main(void)
|
||||||
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
|
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
|
||||||
if (waveLength < 1) waveLength = 1;
|
if (waveLength < 1) waveLength = 1;
|
||||||
|
|
||||||
// Write sine wave.
|
// Write sine wave
|
||||||
for (int i = 0; i < waveLength*2; i++)
|
for (int i = 0; i < waveLength*2; i++)
|
||||||
{
|
{
|
||||||
data[i] = (short)(sinf(((2*PI*(float)i/waveLength)))*32000);
|
data[i] = (short)(sinf(((2*PI*(float)i/waveLength)))*32000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale read cursor's position to minimize transition artifacts
|
// Scale read cursor's position to minimize transition artifacts
|
||||||
readCursor = (int)(readCursor * ((float)waveLength / (float)oldWavelength));
|
//readCursor = (int)(readCursor * ((float)waveLength / (float)oldWavelength));
|
||||||
oldFrequency = frequency;
|
oldFrequency = frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// Refill audio stream if required
|
// Refill audio stream if required
|
||||||
if (IsAudioStreamProcessed(stream))
|
if (IsAudioStreamProcessed(stream))
|
||||||
{
|
{
|
||||||
|
|
@ -131,6 +166,7 @@ int main(void)
|
||||||
// Copy finished frame to audio stream
|
// Copy finished frame to audio stream
|
||||||
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
|
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Global Variables Definition
|
// Global Variables Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Declaration
|
// Module Functions Declaration
|
||||||
|
|
|
||||||
|
|
@ -92,20 +92,20 @@ int main(void)
|
||||||
// Draw axis: left joystick
|
// Draw axis: left joystick
|
||||||
DrawCircle(259, 152, 39, BLACK);
|
DrawCircle(259, 152, 39, BLACK);
|
||||||
DrawCircle(259, 152, 34, LIGHTGRAY);
|
DrawCircle(259, 152, 34, LIGHTGRAY);
|
||||||
DrawCircle(259 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X)*20),
|
DrawCircle(259 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X)*20),
|
||||||
152 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK);
|
152 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK);
|
||||||
|
|
||||||
// Draw axis: right joystick
|
// Draw axis: right joystick
|
||||||
DrawCircle(461, 237, 38, BLACK);
|
DrawCircle(461, 237, 38, BLACK);
|
||||||
DrawCircle(461, 237, 33, LIGHTGRAY);
|
DrawCircle(461, 237, 33, LIGHTGRAY);
|
||||||
DrawCircle(461 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*20),
|
DrawCircle(461 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*20),
|
||||||
237 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
|
237 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
|
||||||
|
|
||||||
// Draw axis: left-right triggers
|
// Draw axis: left-right triggers
|
||||||
DrawRectangle(170, 30, 15, 70, GRAY);
|
DrawRectangle(170, 30, 15, 70, GRAY);
|
||||||
DrawRectangle(604, 30, 15, 70, GRAY);
|
DrawRectangle(604, 30, 15, 70, GRAY);
|
||||||
DrawRectangle(170, 30, 15, (((1 + (int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER))/2)*70), RED);
|
DrawRectangle(170, 30, 15, (int)(((1 + GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER))/2)*70), RED);
|
||||||
DrawRectangle(604, 30, 15, (((1 + (int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER))/2)*70), RED);
|
DrawRectangle(604, 30, 15, (int)(((1 + GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER))/2)*70), RED);
|
||||||
|
|
||||||
//DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK);
|
//DrawText(TextFormat("Xbox axis LT: %02.02f", GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER)), 10, 40, 10, BLACK);
|
||||||
//DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK);
|
//DrawText(TextFormat("Xbox axis RT: %02.02f", GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK);
|
||||||
|
|
@ -140,20 +140,20 @@ int main(void)
|
||||||
// Draw axis: left joystick
|
// Draw axis: left joystick
|
||||||
DrawCircle(319, 255, 35, BLACK);
|
DrawCircle(319, 255, 35, BLACK);
|
||||||
DrawCircle(319, 255, 31, LIGHTGRAY);
|
DrawCircle(319, 255, 31, LIGHTGRAY);
|
||||||
DrawCircle(319 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) * 20),
|
DrawCircle(319 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) * 20),
|
||||||
255 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) * 20), 25, BLACK);
|
255 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) * 20), 25, BLACK);
|
||||||
|
|
||||||
// Draw axis: right joystick
|
// Draw axis: right joystick
|
||||||
DrawCircle(475, 255, 35, BLACK);
|
DrawCircle(475, 255, 35, BLACK);
|
||||||
DrawCircle(475, 255, 31, LIGHTGRAY);
|
DrawCircle(475, 255, 31, LIGHTGRAY);
|
||||||
DrawCircle(475 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*20),
|
DrawCircle(475 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 20),
|
||||||
255 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
|
255 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 20), 25, BLACK);
|
||||||
|
|
||||||
// Draw axis: left-right triggers
|
// Draw axis: left-right triggers
|
||||||
DrawRectangle(169, 48, 15, 70, GRAY);
|
DrawRectangle(169, 48, 15, 70, GRAY);
|
||||||
DrawRectangle(611, 48, 15, 70, GRAY);
|
DrawRectangle(611, 48, 15, 70, GRAY);
|
||||||
DrawRectangle(169, 48, 15, (((1 - (int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER)) / 2) * 70), RED);
|
DrawRectangle(169, 48, 15, (int)(((1 - GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER)) / 2) * 70), RED);
|
||||||
DrawRectangle(611, 48, 15, (((1 - (int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)) / 2) * 70), RED);
|
DrawRectangle(611, 48, 15, (int)(((1 - GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)) / 2) * 70), RED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,11 @@ int main(void)
|
||||||
|
|
||||||
// Initialize framebuffer for stereo rendering
|
// Initialize framebuffer for stereo rendering
|
||||||
// NOTE: Screen size should match HMD aspect ratio
|
// NOTE: Screen size should match HMD aspect ratio
|
||||||
RenderTexture2D target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
RenderTexture2D target = LoadRenderTexture(device.hResolution, device.vResolution);
|
||||||
|
|
||||||
|
// The target's height is flipped (in the source Rectangle), due to OpenGL reasons
|
||||||
|
Rectangle sourceRec = { 0.0f, 0.0f, (float)target.texture.width, -(float)target.texture.height };
|
||||||
|
Rectangle destRec = { 0.0f, 0.0f, (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||||
|
|
||||||
// Define the camera to look into our 3d world
|
// Define the camera to look into our 3d world
|
||||||
Camera camera = { 0 };
|
Camera camera = { 0 };
|
||||||
|
|
@ -121,8 +125,7 @@ int main(void)
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
BeginShaderMode(distortion);
|
BeginShaderMode(distortion);
|
||||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
|
DrawTexturePro(target.texture, sourceRec, destRec, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
|
||||||
(float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
|
||||||
EndShaderMode();
|
EndShaderMode();
|
||||||
DrawFPS(10, 10);
|
DrawFPS(10, 10);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|
|
||||||
|
|
@ -121,9 +121,22 @@ int main(void)
|
||||||
cursorColor = ORANGE;
|
cursorColor = ORANGE;
|
||||||
hitObjectName = "Box";
|
hitObjectName = "Box";
|
||||||
|
|
||||||
// Check ray collision against model
|
// Check ray collision against model meshes
|
||||||
// NOTE: It considers model.transform matrix!
|
RayCollision meshHitInfo = { 0 };
|
||||||
RayCollision meshHitInfo = GetRayCollisionModel(ray, tower);
|
for (int m = 0; m < tower.meshCount; m++)
|
||||||
|
{
|
||||||
|
// NOTE: We consider the model.transform for the collision check but
|
||||||
|
// it can be checked against any transform Matrix, used when checking against same
|
||||||
|
// model drawn multiple times with multiple transforms
|
||||||
|
meshHitInfo = GetRayCollisionMesh(ray, tower.meshes[m], tower.transform);
|
||||||
|
if (meshHitInfo.hit)
|
||||||
|
{
|
||||||
|
// Save the closest hit mesh
|
||||||
|
if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo;
|
||||||
|
|
||||||
|
break; // Stop once one mesh collision is detected, the colliding mesh is m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (meshHitInfo.hit)
|
if (meshHitInfo.hit)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - hot reloading");
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - hot reloading");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -217,6 +217,12 @@ int main(void)
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
// Free allocated matrices
|
||||||
|
RL_FREE(rotations);
|
||||||
|
RL_FREE(rotationsInc);
|
||||||
|
RL_FREE(translations);
|
||||||
|
RL_FREE(transforms);
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - raymarching shapes");
|
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - raymarching shapes");
|
||||||
|
|
@ -77,9 +77,7 @@ int main(void)
|
||||||
// Check if screen is resized
|
// Check if screen is resized
|
||||||
if (IsWindowResized())
|
if (IsWindowResized())
|
||||||
{
|
{
|
||||||
screenWidth = GetScreenWidth();
|
float resolution[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||||
screenHeight = GetScreenHeight();
|
|
||||||
float resolution[2] = { (float)screenWidth, (float)screenHeight };
|
|
||||||
SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
|
SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -93,10 +91,10 @@ int main(void)
|
||||||
// We only draw a white full-screen rectangle,
|
// We only draw a white full-screen rectangle,
|
||||||
// frame is generated in shader using raymarching
|
// frame is generated in shader using raymarching
|
||||||
BeginShaderMode(shader);
|
BeginShaderMode(shader);
|
||||||
DrawRectangle(0, 0, screenWidth, screenHeight, WHITE);
|
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), WHITE);
|
||||||
EndShaderMode();
|
EndShaderMode();
|
||||||
|
|
||||||
DrawText("(c) Raymarching shader by Iñigo Quilez. MIT License.", screenWidth - 280, screenHeight - 20, 10, BLACK);
|
DrawText("(c) Raymarching shader by Iñigo Quilez. MIT License.", GetScreenWidth() - 280, GetScreenHeight() - 20, 10, BLACK);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,7 @@ int main(void)
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
mousePosition = GetMousePosition();
|
mousePosition = GetMousePosition();
|
||||||
|
|
||||||
if (CheckCollisionPointRec(mousePosition, rec) &&
|
if (CheckCollisionPointRec(mousePosition, (Rectangle){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE }))
|
||||||
CheckCollisionPointRec(mousePosition, (Rectangle){ rec.x + rec.width - MOUSE_SCALE_MARK_SIZE, rec.y + rec.height - MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE, MOUSE_SCALE_MARK_SIZE }))
|
|
||||||
{
|
{
|
||||||
mouseScaleReady = true;
|
mouseScaleReady = true;
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) mouseScaleMode = true;
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) mouseScaleMode = true;
|
||||||
|
|
@ -56,9 +55,14 @@ int main(void)
|
||||||
rec.width = (mousePosition.x - rec.x);
|
rec.width = (mousePosition.x - rec.x);
|
||||||
rec.height = (mousePosition.y - rec.y);
|
rec.height = (mousePosition.y - rec.y);
|
||||||
|
|
||||||
|
// Check minimum rec size
|
||||||
if (rec.width < MOUSE_SCALE_MARK_SIZE) rec.width = MOUSE_SCALE_MARK_SIZE;
|
if (rec.width < MOUSE_SCALE_MARK_SIZE) rec.width = MOUSE_SCALE_MARK_SIZE;
|
||||||
if (rec.height < MOUSE_SCALE_MARK_SIZE) rec.height = MOUSE_SCALE_MARK_SIZE;
|
if (rec.height < MOUSE_SCALE_MARK_SIZE) rec.height = MOUSE_SCALE_MARK_SIZE;
|
||||||
|
|
||||||
|
// Check maximum rec size
|
||||||
|
if (rec.width > (GetScreenWidth() - rec.x)) rec.width = GetScreenWidth() - rec.x;
|
||||||
|
if (rec.height > (GetScreenHeight() - rec.y)) rec.height = GetScreenHeight() - rec.y;
|
||||||
|
|
||||||
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) mouseScaleMode = false;
|
if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT)) mouseScaleMode = false;
|
||||||
}
|
}
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
int screenWidth = 800;
|
const int screenWidth = 800;
|
||||||
int screenHeight = 450;
|
const int screenHeight = 450;
|
||||||
|
|
||||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE); // Make the window resizable
|
SetConfigFlags(FLAG_WINDOW_RESIZABLE); // Make the window resizable
|
||||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - Draw part of a texture tiled");
|
InitWindow(screenWidth, screenHeight, "raylib [textures] example - Draw part of a texture tiled");
|
||||||
|
|
@ -71,9 +71,6 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
screenWidth = GetScreenWidth();
|
|
||||||
screenHeight = GetScreenHeight();
|
|
||||||
|
|
||||||
// Handle mouse
|
// Handle mouse
|
||||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
|
||||||
{
|
{
|
||||||
|
|
@ -122,11 +119,11 @@ int main(int argc, char **argv)
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
// Draw the tiled area
|
// Draw the tiled area
|
||||||
DrawTextureTiled(texPattern, recPattern[activePattern], (Rectangle){(float)OPT_WIDTH+MARGIN_SIZE, (float)MARGIN_SIZE, screenWidth - OPT_WIDTH - 2.0f*MARGIN_SIZE, screenHeight - 2.0f*MARGIN_SIZE},
|
DrawTextureTiled(texPattern, recPattern[activePattern], (Rectangle){(float)OPT_WIDTH+MARGIN_SIZE, (float)MARGIN_SIZE, GetScreenWidth() - OPT_WIDTH - 2.0f*MARGIN_SIZE, GetScreenHeight() - 2.0f*MARGIN_SIZE},
|
||||||
(Vector2){0.0f, 0.0f}, rotation, scale, colors[activeCol]);
|
(Vector2){0.0f, 0.0f}, rotation, scale, colors[activeCol]);
|
||||||
|
|
||||||
// Draw options
|
// Draw options
|
||||||
DrawRectangle(MARGIN_SIZE, MARGIN_SIZE, OPT_WIDTH - MARGIN_SIZE, screenHeight - 2*MARGIN_SIZE, ColorAlpha(LIGHTGRAY, 0.5f));
|
DrawRectangle(MARGIN_SIZE, MARGIN_SIZE, OPT_WIDTH - MARGIN_SIZE, GetScreenHeight() - 2*MARGIN_SIZE, ColorAlpha(LIGHTGRAY, 0.5f));
|
||||||
|
|
||||||
DrawText("Select Pattern", 2 + MARGIN_SIZE, 30 + MARGIN_SIZE, 10, BLACK);
|
DrawText("Select Pattern", 2 + MARGIN_SIZE, 30 + MARGIN_SIZE, 10, BLACK);
|
||||||
DrawTexture(texPattern, 2 + MARGIN_SIZE, 40 + MARGIN_SIZE, BLACK);
|
DrawTexture(texPattern, 2 + MARGIN_SIZE, 40 + MARGIN_SIZE, BLACK);
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,10 @@ parse:
|
||||||
./raylib_parser -i ../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
|
./raylib_parser -i ../src/raylib.h -o raylib_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
|
||||||
./raylib_parser -i ../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
|
./raylib_parser -i ../src/raymath.h -o raymath_api.$(EXTENSION) -f $(FORMAT) -d RMAPI
|
||||||
./raylib_parser -i ../src/extras/easings.h -o easings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
|
./raylib_parser -i ../src/extras/easings.h -o easings_api.$(EXTENSION) -f $(FORMAT) -d EASEDEF
|
||||||
./raylib_parser -i ../src/extras/physac.h -o physac_api.$(EXTENSION) -f $(FORMAT) -d PHYSACDEF
|
./raylib_parser -i ../src/extras/physac.h -o physac_api.$(EXTENSION) -f $(FORMAT) -d PHYSACDEF -t "PHYSAC IMPLEMENTATION"
|
||||||
./raylib_parser -i ../src/extras/raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI
|
./raylib_parser -i ../src/extras/raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI -t "RAYGUI IMPLEMENTATION"
|
||||||
./raylib_parser -i ../src/extras/rmem.h -o rmem_api.$(EXTENSION) -f $(FORMAT) -d RMEMAPI
|
./raylib_parser -i ../src/extras/rmem.h -o rmem_api.$(EXTENSION) -f $(FORMAT) -d RMEMAPI -t "RMEM IMPLEMENTATION"
|
||||||
./raylib_parser -i ../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
|
./raylib_parser -i ../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI -t "RLGL IMPLEMENTATION"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f raylib_parser *.json *.txt *.xml *.lua
|
rm -f raylib_parser *.json *.txt *.xml *.lua
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,59 @@
|
||||||
<?xml version="1.0" encoding="Windows-1252" ?>
|
<?xml version="1.0" encoding="Windows-1252" ?>
|
||||||
<raylibAPI>
|
<raylibAPI>
|
||||||
|
<Defines count="52">
|
||||||
|
<Define name="RAYLIB_H" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="RAYLIB_VERSION" type="STRING" value="4.1-dev" desc="" />
|
||||||
|
<Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="We are building the library as a Win32 shared library (.dll)" />
|
||||||
|
<Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
|
||||||
|
<Define name="DEG2RAD" type="FLOAT_MATH" value="(PI/180.0f)" desc="" />
|
||||||
|
<Define name="RAD2DEG" type="FLOAT_MATH" value="(180.0f/PI)" desc="" />
|
||||||
|
<Define name="RL_MALLOC(sz)" type="MACRO" value="malloc(sz)" desc="" />
|
||||||
|
<Define name="RL_CALLOC(n,sz)" type="MACRO" value="calloc(n,sz)" desc="" />
|
||||||
|
<Define name="RL_REALLOC(ptr,sz)" type="MACRO" value="realloc(ptr,sz)" desc="" />
|
||||||
|
<Define name="RL_FREE(ptr)" type="MACRO" value="free(ptr)" desc="" />
|
||||||
|
<Define name="CLITERAL(type)" type="MACRO" value="type" desc="" />
|
||||||
|
<Define name="RL_COLOR_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="RL_RECTANGLE_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="RL_VECTOR2_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="RL_VECTOR3_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="RL_VECTOR4_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="RL_QUATERNION_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="RL_MATRIX_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="LIGHTGRAY" type="COLOR" value="CLITERAL(Color){ 200, 200, 200, 255 }" desc="Light Gray" />
|
||||||
|
<Define name="GRAY" type="COLOR" value="CLITERAL(Color){ 130, 130, 130, 255 }" desc="Gray" />
|
||||||
|
<Define name="DARKGRAY" type="COLOR" value="CLITERAL(Color){ 80, 80, 80, 255 }" desc="Dark Gray" />
|
||||||
|
<Define name="YELLOW" type="COLOR" value="CLITERAL(Color){ 253, 249, 0, 255 }" desc="Yellow" />
|
||||||
|
<Define name="GOLD" type="COLOR" value="CLITERAL(Color){ 255, 203, 0, 255 }" desc="Gold" />
|
||||||
|
<Define name="ORANGE" type="COLOR" value="CLITERAL(Color){ 255, 161, 0, 255 }" desc="Orange" />
|
||||||
|
<Define name="PINK" type="COLOR" value="CLITERAL(Color){ 255, 109, 194, 255 }" desc="Pink" />
|
||||||
|
<Define name="RED" type="COLOR" value="CLITERAL(Color){ 230, 41, 55, 255 }" desc="Red" />
|
||||||
|
<Define name="MAROON" type="COLOR" value="CLITERAL(Color){ 190, 33, 55, 255 }" desc="Maroon" />
|
||||||
|
<Define name="GREEN" type="COLOR" value="CLITERAL(Color){ 0, 228, 48, 255 }" desc="Green" />
|
||||||
|
<Define name="LIME" type="COLOR" value="CLITERAL(Color){ 0, 158, 47, 255 }" desc="Lime" />
|
||||||
|
<Define name="DARKGREEN" type="COLOR" value="CLITERAL(Color){ 0, 117, 44, 255 }" desc="Dark Green" />
|
||||||
|
<Define name="SKYBLUE" type="COLOR" value="CLITERAL(Color){ 102, 191, 255, 255 }" desc="Sky Blue" />
|
||||||
|
<Define name="BLUE" type="COLOR" value="CLITERAL(Color){ 0, 121, 241, 255 }" desc="Blue" />
|
||||||
|
<Define name="DARKBLUE" type="COLOR" value="CLITERAL(Color){ 0, 82, 172, 255 }" desc="Dark Blue" />
|
||||||
|
<Define name="PURPLE" type="COLOR" value="CLITERAL(Color){ 200, 122, 255, 255 }" desc="Purple" />
|
||||||
|
<Define name="VIOLET" type="COLOR" value="CLITERAL(Color){ 135, 60, 190, 255 }" desc="Violet" />
|
||||||
|
<Define name="DARKPURPLE" type="COLOR" value="CLITERAL(Color){ 112, 31, 126, 255 }" desc="Dark Purple" />
|
||||||
|
<Define name="BEIGE" type="COLOR" value="CLITERAL(Color){ 211, 176, 131, 255 }" desc="Beige" />
|
||||||
|
<Define name="BROWN" type="COLOR" value="CLITERAL(Color){ 127, 106, 79, 255 }" desc="Brown" />
|
||||||
|
<Define name="DARKBROWN" type="COLOR" value="CLITERAL(Color){ 76, 63, 47, 255 }" desc="Dark Brown" />
|
||||||
|
<Define name="WHITE" type="COLOR" value="CLITERAL(Color){ 255, 255, 255, 255 }" desc="White" />
|
||||||
|
<Define name="BLACK" type="COLOR" value="CLITERAL(Color){ 0, 0, 0, 255 }" desc="Black" />
|
||||||
|
<Define name="BLANK" type="COLOR" value="CLITERAL(Color){ 0, 0, 0, 0 }" desc="Blank (Transparent)" />
|
||||||
|
<Define name="MAGENTA" type="COLOR" value="CLITERAL(Color){ 255, 0, 255, 255 }" desc="Magenta" />
|
||||||
|
<Define name="RAYWHITE" type="COLOR" value="CLITERAL(Color){ 245, 245, 245, 255 }" desc="My own White (raylib logo)" />
|
||||||
|
<Define name="RL_BOOL_TYPE" type="GUARD" value="" desc="" />
|
||||||
|
<Define name="MOUSE_LEFT_BUTTON" type="UNKNOWN" value="MOUSE_BUTTON_LEFT" desc="" />
|
||||||
|
<Define name="MOUSE_RIGHT_BUTTON" type="UNKNOWN" value="MOUSE_BUTTON_RIGHT" desc="" />
|
||||||
|
<Define name="MOUSE_MIDDLE_BUTTON" type="UNKNOWN" value="MOUSE_BUTTON_MIDDLE" desc="" />
|
||||||
|
<Define name="MATERIAL_MAP_DIFFUSE" type="UNKNOWN" value="MATERIAL_MAP_ALBEDO" desc="" />
|
||||||
|
<Define name="MATERIAL_MAP_SPECULAR" type="UNKNOWN" value="MATERIAL_MAP_METALNESS" desc="" />
|
||||||
|
<Define name="SHADER_LOC_MAP_DIFFUSE" type="UNKNOWN" value="SHADER_LOC_MAP_ALBEDO" desc="" />
|
||||||
|
<Define name="SHADER_LOC_MAP_SPECULAR" type="UNKNOWN" value="SHADER_LOC_MAP_METALNESS" desc="" />
|
||||||
|
</Defines>
|
||||||
<Structs count="31">
|
<Structs count="31">
|
||||||
<Struct name="Vector2" fieldCount="2" desc="Vector2, 2 components">
|
<Struct name="Vector2" fieldCount="2" desc="Vector2, 2 components">
|
||||||
<Field type="float" name="x" desc="Vector x component" />
|
<Field type="float" name="x" desc="Vector x component" />
|
||||||
|
|
@ -16,11 +70,23 @@
|
||||||
<Field type="float" name="z" desc="Vector z component" />
|
<Field type="float" name="z" desc="Vector z component" />
|
||||||
<Field type="float" name="w" desc="Vector w component" />
|
<Field type="float" name="w" desc="Vector w component" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="Matrix" fieldCount="4" desc="Matrix, 4x4 components, column major, OpenGL style, right handed">
|
<Struct name="Matrix" fieldCount="16" desc="Matrix, 4x4 components, column major, OpenGL style, right handed">
|
||||||
<Field type="float" name="m0, m4, m8, m12" desc="Matrix first row (4 components)" />
|
<Field type="float" name="m0" desc="Matrix first row (4 components)" />
|
||||||
<Field type="float" name="m1, m5, m9, m13" desc="Matrix second row (4 components)" />
|
<Field type="float" name="m4" desc="Matrix first row (4 components)" />
|
||||||
<Field type="float" name="m2, m6, m10, m14" desc="Matrix third row (4 components)" />
|
<Field type="float" name="m8" desc="Matrix first row (4 components)" />
|
||||||
<Field type="float" name="m3, m7, m11, m15" desc="Matrix fourth row (4 components)" />
|
<Field type="float" name="m12" desc="Matrix first row (4 components)" />
|
||||||
|
<Field type="float" name="m1" desc="Matrix second row (4 components)" />
|
||||||
|
<Field type="float" name="m5" desc="Matrix second row (4 components)" />
|
||||||
|
<Field type="float" name="m9" desc="Matrix second row (4 components)" />
|
||||||
|
<Field type="float" name="m13" desc="Matrix second row (4 components)" />
|
||||||
|
<Field type="float" name="m2" desc="Matrix third row (4 components)" />
|
||||||
|
<Field type="float" name="m6" desc="Matrix third row (4 components)" />
|
||||||
|
<Field type="float" name="m10" desc="Matrix third row (4 components)" />
|
||||||
|
<Field type="float" name="m14" desc="Matrix third row (4 components)" />
|
||||||
|
<Field type="float" name="m3" desc="Matrix fourth row (4 components)" />
|
||||||
|
<Field type="float" name="m7" desc="Matrix fourth row (4 components)" />
|
||||||
|
<Field type="float" name="m11" desc="Matrix fourth row (4 components)" />
|
||||||
|
<Field type="float" name="m15" desc="Matrix fourth row (4 components)" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="Color" fieldCount="4" desc="Color, 4 components, R8G8B8A8 (32bit)">
|
<Struct name="Color" fieldCount="4" desc="Color, 4 components, R8G8B8A8 (32bit)">
|
||||||
<Field type="unsigned char" name="r" desc="Color red value" />
|
<Field type="unsigned char" name="r" desc="Color red value" />
|
||||||
|
|
@ -94,7 +160,7 @@
|
||||||
<Field type="int" name="triangleCount" desc="Number of triangles stored (indexed or not)" />
|
<Field type="int" name="triangleCount" desc="Number of triangles stored (indexed or not)" />
|
||||||
<Field type="float *" name="vertices" desc="Vertex position (XYZ - 3 components per vertex) (shader-location = 0)" />
|
<Field type="float *" name="vertices" desc="Vertex position (XYZ - 3 components per vertex) (shader-location = 0)" />
|
||||||
<Field type="float *" name="texcoords" desc="Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)" />
|
<Field type="float *" name="texcoords" desc="Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)" />
|
||||||
<Field type="float *" name="texcoords2" desc="Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)" />
|
<Field type="float *" name="texcoords2" desc="Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5)" />
|
||||||
<Field type="float *" name="normals" desc="Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)" />
|
<Field type="float *" name="normals" desc="Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)" />
|
||||||
<Field type="float *" name="tangents" desc="Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)" />
|
<Field type="float *" name="tangents" desc="Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)" />
|
||||||
<Field type="unsigned char *" name="colors" desc="Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)" />
|
<Field type="unsigned char *" name="colors" desc="Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)" />
|
||||||
|
|
@ -118,7 +184,7 @@
|
||||||
<Struct name="Material" fieldCount="3" desc="Material, includes shader and maps">
|
<Struct name="Material" fieldCount="3" desc="Material, includes shader and maps">
|
||||||
<Field type="Shader" name="shader" desc="Material shader" />
|
<Field type="Shader" name="shader" desc="Material shader" />
|
||||||
<Field type="MaterialMap *" name="maps" desc="Material maps array (MAX_MATERIAL_MAPS)" />
|
<Field type="MaterialMap *" name="maps" desc="Material maps array (MAX_MATERIAL_MAPS)" />
|
||||||
<Field type="float" name="params[4]" desc="Material generic parameters (if required)" />
|
<Field type="float[4]" name="params" desc="Material generic parameters (if required)" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="Transform" fieldCount="3" desc="Transform, vectex transformation data">
|
<Struct name="Transform" fieldCount="3" desc="Transform, vectex transformation data">
|
||||||
<Field type="Vector3" name="translation" desc="Translation" />
|
<Field type="Vector3" name="translation" desc="Translation" />
|
||||||
|
|
@ -126,7 +192,7 @@
|
||||||
<Field type="Vector3" name="scale" desc="Scale" />
|
<Field type="Vector3" name="scale" desc="Scale" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="BoneInfo" fieldCount="2" desc="Bone, skeletal animation bone">
|
<Struct name="BoneInfo" fieldCount="2" desc="Bone, skeletal animation bone">
|
||||||
<Field type="char" name="name[32]" desc="Bone name" />
|
<Field type="char[32]" name="name" desc="Bone name" />
|
||||||
<Field type="int" name="parent" desc="Bone parent" />
|
<Field type="int" name="parent" desc="Bone parent" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="Model" fieldCount="9" desc="Model, meshes, materials and animation data">
|
<Struct name="Model" fieldCount="9" desc="Model, meshes, materials and animation data">
|
||||||
|
|
@ -167,8 +233,9 @@
|
||||||
<Field type="unsigned int" name="channels" desc="Number of channels (1-mono, 2-stereo, ...)" />
|
<Field type="unsigned int" name="channels" desc="Number of channels (1-mono, 2-stereo, ...)" />
|
||||||
<Field type="void *" name="data" desc="Buffer data pointer" />
|
<Field type="void *" name="data" desc="Buffer data pointer" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="AudioStream" fieldCount="4" desc="AudioStream, custom audio stream">
|
<Struct name="AudioStream" fieldCount="5" desc="AudioStream, custom audio stream">
|
||||||
<Field type="rAudioBuffer *" name="buffer" desc="Pointer to internal data used by the audio system" />
|
<Field type="rAudioBuffer *" name="buffer" desc="Pointer to internal data used by the audio system" />
|
||||||
|
<Field type="rAudioProcessor *" name="processor" desc="Pointer to internal data processor, useful for audio effects" />
|
||||||
<Field type="unsigned int" name="sampleRate" desc="Frequency (samples per second)" />
|
<Field type="unsigned int" name="sampleRate" desc="Frequency (samples per second)" />
|
||||||
<Field type="unsigned int" name="sampleSize" desc="Bit depth (bits per sample): 8, 16, 32 (24 not supported)" />
|
<Field type="unsigned int" name="sampleSize" desc="Bit depth (bits per sample): 8, 16, 32 (24 not supported)" />
|
||||||
<Field type="unsigned int" name="channels" desc="Number of channels (1-mono, 2-stereo, ...)" />
|
<Field type="unsigned int" name="channels" desc="Number of channels (1-mono, 2-stereo, ...)" />
|
||||||
|
|
@ -193,20 +260,27 @@
|
||||||
<Field type="float" name="eyeToScreenDistance" desc="Distance between eye and display in meters" />
|
<Field type="float" name="eyeToScreenDistance" desc="Distance between eye and display in meters" />
|
||||||
<Field type="float" name="lensSeparationDistance" desc="Lens separation distance in meters" />
|
<Field type="float" name="lensSeparationDistance" desc="Lens separation distance in meters" />
|
||||||
<Field type="float" name="interpupillaryDistance" desc="IPD (distance between pupils) in meters" />
|
<Field type="float" name="interpupillaryDistance" desc="IPD (distance between pupils) in meters" />
|
||||||
<Field type="float" name="lensDistortionValues[4]" desc="Lens distortion constant parameters" />
|
<Field type="float[4]" name="lensDistortionValues" desc="Lens distortion constant parameters" />
|
||||||
<Field type="float" name="chromaAbCorrection[4]" desc="Chromatic aberration correction parameters" />
|
<Field type="float[4]" name="chromaAbCorrection" desc="Chromatic aberration correction parameters" />
|
||||||
</Struct>
|
</Struct>
|
||||||
<Struct name="VrStereoConfig" fieldCount="8" desc="VrStereoConfig, VR stereo rendering configuration for simulator">
|
<Struct name="VrStereoConfig" fieldCount="8" desc="VrStereoConfig, VR stereo rendering configuration for simulator">
|
||||||
<Field type="Matrix" name="projection[2]" desc="VR projection matrices (per eye)" />
|
<Field type="Matrix[2]" name="projection" desc="VR projection matrices (per eye)" />
|
||||||
<Field type="Matrix" name="viewOffset[2]" desc="VR view offset matrices (per eye)" />
|
<Field type="Matrix[2]" name="viewOffset" desc="VR view offset matrices (per eye)" />
|
||||||
<Field type="float" name="leftLensCenter[2]" desc="VR left lens center" />
|
<Field type="float[2]" name="leftLensCenter" desc="VR left lens center" />
|
||||||
<Field type="float" name="rightLensCenter[2]" desc="VR right lens center" />
|
<Field type="float[2]" name="rightLensCenter" desc="VR right lens center" />
|
||||||
<Field type="float" name="leftScreenCenter[2]" desc="VR left screen center" />
|
<Field type="float[2]" name="leftScreenCenter" desc="VR left screen center" />
|
||||||
<Field type="float" name="rightScreenCenter[2]" desc="VR right screen center" />
|
<Field type="float[2]" name="rightScreenCenter" desc="VR right screen center" />
|
||||||
<Field type="float" name="scale[2]" desc="VR distortion scale" />
|
<Field type="float[2]" name="scale" desc="VR distortion scale" />
|
||||||
<Field type="float" name="scaleIn[2]" desc="VR distortion scale in" />
|
<Field type="float[2]" name="scaleIn" desc="VR distortion scale in" />
|
||||||
</Struct>
|
</Struct>
|
||||||
</Structs>
|
</Structs>
|
||||||
|
<Aliases count="5">
|
||||||
|
<Alias type="Quaternion" name="Vector4" desc="Quaternion, 4 components (Vector4 alias)" />
|
||||||
|
<Alias type="Texture2D" name="Texture" desc="Texture2D, same as Texture" />
|
||||||
|
<Alias type="TextureCubemap" name="Texture" desc="TextureCubemap, same as Texture" />
|
||||||
|
<Alias type="RenderTexture2D" name="RenderTexture" desc="RenderTexture2D, same as RenderTexture" />
|
||||||
|
<Alias type="Camera" name="Camera3D" desc="Camera type fallback, defaults to Camera3D" />
|
||||||
|
</Aliases>
|
||||||
<Enums count="21">
|
<Enums count="21">
|
||||||
<Enum name="ConfigFlags" valueCount="14" desc="System/Window config flags">
|
<Enum name="ConfigFlags" valueCount="14" desc="System/Window config flags">
|
||||||
<Value name="FLAG_VSYNC_HINT" integer="64" desc="Set to try enabling V-Sync on GPU" />
|
<Value name="FLAG_VSYNC_HINT" integer="64" desc="Set to try enabling V-Sync on GPU" />
|
||||||
|
|
@ -543,61 +617,34 @@
|
||||||
<Value name="NPATCH_THREE_PATCH_HORIZONTAL" integer="2" desc="Npatch layout: 3x1 tiles" />
|
<Value name="NPATCH_THREE_PATCH_HORIZONTAL" integer="2" desc="Npatch layout: 3x1 tiles" />
|
||||||
</Enum>
|
</Enum>
|
||||||
</Enums>
|
</Enums>
|
||||||
<Defines count="52">
|
<Callbacks count="6">
|
||||||
<Define name="RAYLIB_H" type="GUARD" value="" desc="" />
|
<Callback name="TraceLogCallback" retType="void" paramCount="3" desc="Logging: Redirect trace log messages">
|
||||||
<Define name="RAYLIB_VERSION" type="STRING" value=""4.1-dev"" desc="" />
|
<Param type="int" name="logLevel" desc="" />
|
||||||
<Define name="RLAPI" type="UNKNOWN" value="__declspec(dllexport)" desc="// We are building the library as a Win32 shared library (.dll)" />
|
<Param type="const char *" name="text" desc="" />
|
||||||
<Define name="PI" type="FLOAT" value="3.14159265358979323846" desc="" />
|
<Param type="va_list" name="args" desc="" />
|
||||||
<Define name="DEG2RAD" type="UNKNOWN" value="(PI/180.0f)" desc="" />
|
</Callback>
|
||||||
<Define name="RAD2DEG" type="UNKNOWN" value="(180.0f/PI)" desc="" />
|
<Callback name="LoadFileDataCallback" retType="unsigned char *" paramCount="2" desc="FileIO: Load binary data">
|
||||||
<Define name="RL_MALLOC(sz)" type="MACRO" value="malloc(sz)" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
<Define name="RL_CALLOC(n,sz)" type="MACRO" value="calloc(n,sz)" desc="" />
|
<Param type="unsigned int *" name="bytesRead" desc="" />
|
||||||
<Define name="RL_REALLOC(ptr,sz)" type="MACRO" value="realloc(ptr,sz)" desc="" />
|
</Callback>
|
||||||
<Define name="RL_FREE(ptr)" type="MACRO" value="free(ptr)" desc="" />
|
<Callback name="SaveFileDataCallback" retType="bool" paramCount="3" desc="FileIO: Save binary data">
|
||||||
<Define name="CLITERAL(type)" type="MACRO" value="type" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
<Define name="RL_COLOR_TYPE" type="GUARD" value="" desc="" />
|
<Param type="void *" name="data" desc="" />
|
||||||
<Define name="RL_RECTANGLE_TYPE" type="GUARD" value="" desc="" />
|
<Param type="unsigned int" name="bytesToWrite" desc="" />
|
||||||
<Define name="RL_VECTOR2_TYPE" type="GUARD" value="" desc="" />
|
</Callback>
|
||||||
<Define name="RL_VECTOR3_TYPE" type="GUARD" value="" desc="" />
|
<Callback name="LoadFileTextCallback" retType="char *" paramCount="1" desc="FileIO: Load text data">
|
||||||
<Define name="RL_VECTOR4_TYPE" type="GUARD" value="" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
<Define name="RL_QUATERNION_TYPE" type="GUARD" value="" desc="" />
|
</Callback>
|
||||||
<Define name="RL_MATRIX_TYPE" type="GUARD" value="" desc="" />
|
<Callback name="SaveFileTextCallback" retType="bool" paramCount="2" desc="FileIO: Save text data">
|
||||||
<Define name="LIGHTGRAY" type="COLOR" value="CLITERAL(Color){ 200, 200, 200, 255 }" desc="// Light Gray" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
<Define name="GRAY" type="COLOR" value="CLITERAL(Color){ 130, 130, 130, 255 }" desc="// Gray" />
|
<Param type="char *" name="text" desc="" />
|
||||||
<Define name="DARKGRAY" type="COLOR" value="CLITERAL(Color){ 80, 80, 80, 255 }" desc="// Dark Gray" />
|
</Callback>
|
||||||
<Define name="YELLOW" type="COLOR" value="CLITERAL(Color){ 253, 249, 0, 255 }" desc="// Yellow" />
|
<Callback name="AudioCallback" retType="void" paramCount="2" desc="">
|
||||||
<Define name="GOLD" type="COLOR" value="CLITERAL(Color){ 255, 203, 0, 255 }" desc="// Gold" />
|
<Param type="void *" name="bufferData" desc="" />
|
||||||
<Define name="ORANGE" type="COLOR" value="CLITERAL(Color){ 255, 161, 0, 255 }" desc="// Orange" />
|
<Param type="unsigned int" name="frames" desc="" />
|
||||||
<Define name="PINK" type="COLOR" value="CLITERAL(Color){ 255, 109, 194, 255 }" desc="// Pink" />
|
</Callback>
|
||||||
<Define name="RED" type="COLOR" value="CLITERAL(Color){ 230, 41, 55, 255 }" desc="// Red" />
|
</Callbacks>
|
||||||
<Define name="MAROON" type="COLOR" value="CLITERAL(Color){ 190, 33, 55, 255 }" desc="// Maroon" />
|
<Functions count="499">
|
||||||
<Define name="GREEN" type="COLOR" value="CLITERAL(Color){ 0, 228, 48, 255 }" desc="// Green" />
|
|
||||||
<Define name="LIME" type="COLOR" value="CLITERAL(Color){ 0, 158, 47, 255 }" desc="// Lime" />
|
|
||||||
<Define name="DARKGREEN" type="COLOR" value="CLITERAL(Color){ 0, 117, 44, 255 }" desc="// Dark Green" />
|
|
||||||
<Define name="SKYBLUE" type="COLOR" value="CLITERAL(Color){ 102, 191, 255, 255 }" desc="// Sky Blue" />
|
|
||||||
<Define name="BLUE" type="COLOR" value="CLITERAL(Color){ 0, 121, 241, 255 }" desc="// Blue" />
|
|
||||||
<Define name="DARKBLUE" type="COLOR" value="CLITERAL(Color){ 0, 82, 172, 255 }" desc="// Dark Blue" />
|
|
||||||
<Define name="PURPLE" type="COLOR" value="CLITERAL(Color){ 200, 122, 255, 255 }" desc="// Purple" />
|
|
||||||
<Define name="VIOLET" type="COLOR" value="CLITERAL(Color){ 135, 60, 190, 255 }" desc="// Violet" />
|
|
||||||
<Define name="DARKPURPLE" type="COLOR" value="CLITERAL(Color){ 112, 31, 126, 255 }" desc="// Dark Purple" />
|
|
||||||
<Define name="BEIGE" type="COLOR" value="CLITERAL(Color){ 211, 176, 131, 255 }" desc="// Beige" />
|
|
||||||
<Define name="BROWN" type="COLOR" value="CLITERAL(Color){ 127, 106, 79, 255 }" desc="// Brown" />
|
|
||||||
<Define name="DARKBROWN" type="COLOR" value="CLITERAL(Color){ 76, 63, 47, 255 }" desc="// Dark Brown" />
|
|
||||||
<Define name="WHITE" type="COLOR" value="CLITERAL(Color){ 255, 255, 255, 255 }" desc="// White" />
|
|
||||||
<Define name="BLACK" type="COLOR" value="CLITERAL(Color){ 0, 0, 0, 255 }" desc="// Black" />
|
|
||||||
<Define name="BLANK" type="COLOR" value="CLITERAL(Color){ 0, 0, 0, 0 }" desc="// Blank (Transparent)" />
|
|
||||||
<Define name="MAGENTA" type="COLOR" value="CLITERAL(Color){ 255, 0, 255, 255 }" desc="// Magenta" />
|
|
||||||
<Define name="RAYWHITE" type="COLOR" value="CLITERAL(Color){ 245, 245, 245, 255 }" desc="// My own White (raylib logo)" />
|
|
||||||
<Define name="RL_BOOL_TYPE" type="GUARD" value="" desc="" />
|
|
||||||
<Define name="MOUSE_LEFT_BUTTON" type="UNKNOWN" value="MOUSE_BUTTON_LEFT" desc="" />
|
|
||||||
<Define name="MOUSE_RIGHT_BUTTON" type="UNKNOWN" value="MOUSE_BUTTON_RIGHT" desc="" />
|
|
||||||
<Define name="MOUSE_MIDDLE_BUTTON" type="UNKNOWN" value="MOUSE_BUTTON_MIDDLE" desc="" />
|
|
||||||
<Define name="MATERIAL_MAP_DIFFUSE" type="UNKNOWN" value="MATERIAL_MAP_ALBEDO" desc="" />
|
|
||||||
<Define name="MATERIAL_MAP_SPECULAR" type="UNKNOWN" value="MATERIAL_MAP_METALNESS" desc="" />
|
|
||||||
<Define name="SHADER_LOC_MAP_DIFFUSE" type="UNKNOWN" value="SHADER_LOC_MAP_ALBEDO" desc="" />
|
|
||||||
<Define name="SHADER_LOC_MAP_SPECULAR" type="UNKNOWN" value="SHADER_LOC_MAP_METALNESS" desc="" />
|
|
||||||
</Defines>
|
|
||||||
<Functions count="497">
|
|
||||||
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
||||||
<Param type="int" name="width" desc="" />
|
<Param type="int" name="width" desc="" />
|
||||||
<Param type="int" name="height" desc="" />
|
<Param type="int" name="height" desc="" />
|
||||||
|
|
@ -955,7 +1002,7 @@
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetApplicationDirectory" retType="const char *" paramCount="0" desc="Get the directory if the running application (uses static string)">
|
<Function name="GetApplicationDirectory" retType="const char *" paramCount="0" desc="Get the directory if the running application (uses static string)">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetDirectoryFiles" retType="char **" paramCount="2" desc="Get filenames in a directory path (memory should be freed)">
|
<Function name="GetDirectoryFiles" retType="char **" paramCount="2" desc="Get filenames in a directory path (memory must be freed)">
|
||||||
<Param type="const char *" name="dirPath" desc="" />
|
<Param type="const char *" name="dirPath" desc="" />
|
||||||
<Param type="int *" name="count" desc="" />
|
<Param type="int *" name="count" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
|
@ -966,7 +1013,7 @@
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="IsFileDropped" retType="bool" paramCount="0" desc="Check if a file has been dropped into window">
|
<Function name="IsFileDropped" retType="bool" paramCount="0" desc="Check if a file has been dropped into window">
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetDroppedFiles" retType="char **" paramCount="1" desc="Get dropped files names (memory should be freed)">
|
<Function name="GetDroppedFiles" retType="char **" paramCount="1" desc="Get dropped files names (memory must be freed)">
|
||||||
<Param type="int *" name="count" desc="" />
|
<Param type="int *" name="count" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="ClearDroppedFiles" retType="void" paramCount="0" desc="Clear dropped files paths buffer (free memory)">
|
<Function name="ClearDroppedFiles" retType="void" paramCount="0" desc="Clear dropped files paths buffer (free memory)">
|
||||||
|
|
@ -974,24 +1021,24 @@
|
||||||
<Function name="GetFileModTime" retType="long" paramCount="1" desc="Get file modification time (last write time)">
|
<Function name="GetFileModTime" retType="long" paramCount="1" desc="Get file modification time (last write time)">
|
||||||
<Param type="const char *" name="fileName" desc="" />
|
<Param type="const char *" name="fileName" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="CompressData" retType="unsigned char *" paramCount="3" desc="Compress data (DEFLATE algorithm)">
|
<Function name="CompressData" retType="unsigned char *" paramCount="3" desc="Compress data (DEFLATE algorithm), memory must be MemFree()">
|
||||||
<Param type="const unsigned char *" name="data" desc="" />
|
<Param type="const unsigned char *" name="data" desc="" />
|
||||||
<Param type="int" name="dataLength" desc="" />
|
<Param type="int" name="dataSize" desc="" />
|
||||||
<Param type="int *" name="compDataLength" desc="" />
|
<Param type="int *" name="compDataSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="DecompressData" retType="unsigned char *" paramCount="3" desc="Decompress data (DEFLATE algorithm)">
|
<Function name="DecompressData" retType="unsigned char *" paramCount="3" desc="Decompress data (DEFLATE algorithm), memory must be MemFree()">
|
||||||
<Param type="const unsigned char *" name="compData" desc="" />
|
<Param type="const unsigned char *" name="compData" desc="" />
|
||||||
<Param type="int" name="compDataLength" desc="" />
|
<Param type="int" name="compDataSize" desc="" />
|
||||||
<Param type="int *" name="dataLength" desc="" />
|
<Param type="int *" name="dataSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="EncodeDataBase64" retType="char *" paramCount="3" desc="Encode data to Base64 string">
|
<Function name="EncodeDataBase64" retType="char *" paramCount="3" desc="Encode data to Base64 string, memory must be MemFree()">
|
||||||
<Param type="const unsigned char *" name="data" desc="" />
|
<Param type="const unsigned char *" name="data" desc="" />
|
||||||
<Param type="int" name="dataLength" desc="" />
|
<Param type="int" name="dataSize" desc="" />
|
||||||
<Param type="int *" name="outputLength" desc="" />
|
<Param type="int *" name="outputSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="DecodeDataBase64" retType="unsigned char *" paramCount="2" desc="Decode Base64 string data">
|
<Function name="DecodeDataBase64" retType="unsigned char *" paramCount="2" desc="Decode Base64 string data, memory must be MemFree()">
|
||||||
<Param type="const unsigned char *" name="data" desc="" />
|
<Param type="const unsigned char *" name="data" desc="" />
|
||||||
<Param type="int *" name="outputLength" desc="" />
|
<Param type="int *" name="outputSize" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="SaveStorageValue" retType="bool" paramCount="2" desc="Save integer value to storage file (to defined position), returns true on success">
|
<Function name="SaveStorageValue" retType="bool" paramCount="2" desc="Save integer value to storage file (to defined position), returns true on success">
|
||||||
<Param type="unsigned int" name="position" desc="" />
|
<Param type="unsigned int" name="position" desc="" />
|
||||||
|
|
@ -2451,10 +2498,6 @@
|
||||||
<Param type="Ray" name="ray" desc="" />
|
<Param type="Ray" name="ray" desc="" />
|
||||||
<Param type="BoundingBox" name="box" desc="" />
|
<Param type="BoundingBox" name="box" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
<Function name="GetRayCollisionModel" retType="RayCollision" paramCount="2" desc="Get collision info between ray and model">
|
|
||||||
<Param type="Ray" name="ray" desc="" />
|
|
||||||
<Param type="Model" name="model" desc="" />
|
|
||||||
</Function>
|
|
||||||
<Function name="GetRayCollisionMesh" retType="RayCollision" paramCount="3" desc="Get collision info between ray and mesh">
|
<Function name="GetRayCollisionMesh" retType="RayCollision" paramCount="3" desc="Get collision info between ray and mesh">
|
||||||
<Param type="Ray" name="ray" desc="" />
|
<Param type="Ray" name="ray" desc="" />
|
||||||
<Param type="Mesh" name="mesh" desc="" />
|
<Param type="Mesh" name="mesh" desc="" />
|
||||||
|
|
@ -2666,5 +2709,17 @@
|
||||||
<Function name="SetAudioStreamBufferSizeDefault" retType="void" paramCount="1" desc="Default size for new audio streams">
|
<Function name="SetAudioStreamBufferSizeDefault" retType="void" paramCount="1" desc="Default size for new audio streams">
|
||||||
<Param type="int" name="size" desc="" />
|
<Param type="int" name="size" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name="SetAudioStreamCallback" retType="void" paramCount="2" desc="Audio thread callback to request new data">
|
||||||
|
<Param type="AudioStream" name="stream" desc="" />
|
||||||
|
<Param type="AudioCallback" name="callback" desc="" />
|
||||||
|
</Function>
|
||||||
|
<Function name="AttachAudioStreamProcessor" retType="void" paramCount="2" desc="">
|
||||||
|
<Param type="AudioStream" name="stream" desc="" />
|
||||||
|
<Param type="AudioCallback" name="processor" desc="" />
|
||||||
|
</Function>
|
||||||
|
<Function name="DetachAudioStreamProcessor" retType="void" paramCount="2" desc="">
|
||||||
|
<Param type="AudioStream" name="stream" desc="" />
|
||||||
|
<Param type="AudioCallback" name="processor" desc="" />
|
||||||
|
</Function>
|
||||||
</Functions>
|
</Functions>
|
||||||
</raylibAPI>
|
</raylibAPI>
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,9 @@
|
||||||
cmake_minimum_required(VERSION 3.11) # FetchContent is available in 3.11+
|
cmake_minimum_required(VERSION 3.11) # FetchContent is available in 3.11+
|
||||||
project(example)
|
project(example)
|
||||||
|
|
||||||
|
# Generate compile_commands.json
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
find_package(raylib 4.0.0 QUIET) # QUIET or REQUIRED
|
find_package(raylib 4.0.0 QUIET) # QUIET or REQUIRED
|
||||||
if (NOT raylib_FOUND) # If there's none, fetch and build raylib
|
if (NOT raylib_FOUND) # If there's none, fetch and build raylib
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@ To compile the example, use one of the following dependending on your build targ
|
||||||
Use the following to build for desktop:
|
Use the following to build for desktop:
|
||||||
|
|
||||||
``` bash
|
``` bash
|
||||||
mkdir build
|
cmake -B build
|
||||||
cd build
|
cmake --build build
|
||||||
cmake ..
|
|
||||||
make
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Web
|
### Web
|
||||||
|
|
|
||||||
|
|
@ -104,11 +104,11 @@ export OFILES_SRC := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||||
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
export OFILES := $(OFILES_BIN) $(OFILES_SRC)
|
||||||
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
export HFILES_BIN := $(addsuffix .h,$(subst .,_,$(BINFILES)))
|
||||||
|
|
||||||
export INCLUDE := -I$(RAYLIB_NX)/src $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
export INCLUDE := -I$(RAYLIB_NX)/src -I$(RAYLIB_NX)/src/switch-nx $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||||
-I$(CURDIR)/$(BUILD)
|
-I$(CURDIR)/$(BUILD)
|
||||||
|
|
||||||
export LIBPATHS := -L$(RAYLIB_NX)/src $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
export LIBPATHS := -L$(RAYLIB_NX)/src -L$(RAYLIB_NX)/src/switch-nx $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
||||||
|
|
||||||
ifeq ($(strip $(CONFIG_JSON)),)
|
ifeq ($(strip $(CONFIG_JSON)),)
|
||||||
jsons := $(wildcard *.json)
|
jsons := $(wildcard *.json)
|
||||||
|
|
|
||||||
23
src/Makefile
23
src/Makefile
|
|
@ -437,7 +437,7 @@ ifeq ($(PLATFORM),PLATFORM_NX)
|
||||||
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
LIBDIRS := $(PORTLIBS) $(LIBNX)
|
||||||
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec
|
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec
|
||||||
CFLAGS += -ffunction-sections -fdata-sections $(ARCH) $(foreach dir,$(LIBDIRS),-I$(dir)/include) -D__SWITCH__
|
CFLAGS += -ffunction-sections -fdata-sections $(ARCH) $(foreach dir,$(LIBDIRS),-I$(dir)/include) -D__SWITCH__
|
||||||
INCLUDE_PATHS = -I.
|
INCLUDE_PATHS = -I. -I./switch-nx
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||||
ifeq ($(PLATFORM_OS),BSD)
|
ifeq ($(PLATFORM_OS),BSD)
|
||||||
|
|
@ -536,9 +536,15 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||||
LDLIBS = -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
|
LDLIBS = -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
|
||||||
|
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
|
||||||
|
LDLIBS += -latomic
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_DRM)
|
ifeq ($(PLATFORM),PLATFORM_DRM)
|
||||||
LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl
|
LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl
|
||||||
|
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
|
||||||
|
LDLIBS += -latomic
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||||
LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -lc -lm
|
LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -lc -lm
|
||||||
|
|
@ -696,17 +702,26 @@ nxusb.o : nxusb.c nxusb.h raylib.h
|
||||||
raygui.o : raygui.c
|
raygui.o : raygui.c
|
||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
||||||
raygui.c:
|
raygui.c:
|
||||||
echo #define RAYGUI_IMPLEMENTATION > raygui.c
|
ifeq ($(PLATFORM_SHELL), cmd)
|
||||||
echo #include "$(RAYLIB_MODULE_RAYGUI_PATH)/raygui.h" >> raygui.c
|
@echo #define RAYGUI_IMPLEMENTATION > raygui.c
|
||||||
|
@echo #include "$(RAYLIB_MODULE_RAYGUI_PATH)/raygui.h" >> raygui.c
|
||||||
|
else
|
||||||
|
@echo "#define RAYGUI_IMPLEMENTATION" > raygui.c
|
||||||
|
@echo "#include \"$(RAYLIB_MODULE_RAYGUI_PATH)/raygui.h\"" >> raygui.c
|
||||||
|
endif
|
||||||
|
|
||||||
# Compile physac module
|
# Compile physac module
|
||||||
# NOTE: physac header should be distributed with raylib.h
|
# NOTE: physac header should be distributed with raylib.h
|
||||||
physac.o : physac.c
|
physac.o : physac.c
|
||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
||||||
physac.c:
|
physac.c:
|
||||||
|
ifeq ($(PLATFORM_SHELL), cmd)
|
||||||
@echo #define PHYSAC_IMPLEMENTATION > physac.c
|
@echo #define PHYSAC_IMPLEMENTATION > physac.c
|
||||||
@echo #include "$(RAYLIB_MODULE_PHYSAC_PATH)/physac.h" >> physac.c
|
@echo #include "$(RAYLIB_MODULE_PHYSAC_PATH)/physac.h" >> physac.c
|
||||||
|
else
|
||||||
|
@echo "#define PHYSAC_IMPLEMENTATION" > physac.c
|
||||||
|
@echo "#include \"$(RAYLIB_MODULE_PHYSAC_PATH)/physac.h\"" >> physac.c
|
||||||
|
endif
|
||||||
# Compile android_native_app_glue module
|
# Compile android_native_app_glue module
|
||||||
android_native_app_glue.o : $(NATIVE_APP_GLUE)/android_native_app_glue.c
|
android_native_app_glue.o : $(NATIVE_APP_GLUE)/android_native_app_glue.c
|
||||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
pub fn Pkg(srcdir: []const u8) type {
|
|
||||||
return struct {
|
|
||||||
pub fn addRaylib(b: *std.build.Builder, target: std.zig.CrossTarget) *std.build.LibExeObjStep {
|
pub fn addRaylib(b: *std.build.Builder, target: std.zig.CrossTarget) *std.build.LibExeObjStep {
|
||||||
// Standard release options allow the person running `zig build` to select
|
// Standard release options allow the person running `zig build` to select
|
||||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||||
|
|
@ -76,14 +74,8 @@ pub fn Pkg(srcdir: []const u8) type {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib.setOutputDir("./");
|
|
||||||
raylib.install();
|
|
||||||
return raylib;
|
return raylib;
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const lib = Pkg(".");
|
|
||||||
|
|
||||||
pub fn build(b: *std.build.Builder) void {
|
pub fn build(b: *std.build.Builder) void {
|
||||||
// Standard target options allows the person running `zig build` to choose
|
// Standard target options allows the person running `zig build` to choose
|
||||||
|
|
@ -92,5 +84,13 @@ pub fn build(b: *std.build.Builder) void {
|
||||||
// for restricting supported target set are available.
|
// for restricting supported target set are available.
|
||||||
const target = b.standardTargetOptions(.{});
|
const target = b.standardTargetOptions(.{});
|
||||||
|
|
||||||
_ = lib.addRaylib(b, target);
|
const lib = addRaylib(b, target);
|
||||||
|
lib.setOutputDir(srcdir);
|
||||||
|
lib.install();
|
||||||
|
}
|
||||||
|
|
||||||
|
const srcdir = getSrcDir();
|
||||||
|
|
||||||
|
fn getSrcDir() []const u8 {
|
||||||
|
return std.fs.path.dirname(@src().file) orelse ".";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
33687
src/external/miniaudio.h
vendored
33687
src/external/miniaudio.h
vendored
File diff suppressed because it is too large
Load Diff
233
src/external/miniaudio_sdl.h
vendored
Normal file
233
src/external/miniaudio_sdl.h
vendored
Normal file
|
|
@ -0,0 +1,233 @@
|
||||||
|
/******************************************************************************
|
||||||
|
|
||||||
|
SDL Backend
|
||||||
|
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ma_uint32 deviceID;
|
||||||
|
} device_sdl;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ma_handle hSDL;
|
||||||
|
ma_proc SDL_InitSubSystem;
|
||||||
|
ma_proc SDL_QuitSubSystem;
|
||||||
|
ma_proc SDL_GetNumAudioDevices;
|
||||||
|
ma_proc SDL_GetAudioDeviceName;
|
||||||
|
ma_proc SDL_CloseAudioDevice;
|
||||||
|
ma_proc SDL_OpenAudioDevice;
|
||||||
|
ma_proc SDL_PauseAudioDevice;
|
||||||
|
} context_sdl;
|
||||||
|
|
||||||
|
|
||||||
|
#define MA_SDL_INIT_AUDIO 0x00000010
|
||||||
|
#define MA_AUDIO_U8 0x0008
|
||||||
|
#define MA_AUDIO_S16 0x8010
|
||||||
|
#define MA_AUDIO_S32 0x8020
|
||||||
|
#define MA_AUDIO_F32 0x8120
|
||||||
|
#define MA_SDL_AUDIO_ALLOW_FREQUENCY_CHANGE 0x00000001
|
||||||
|
#define MA_SDL_AUDIO_ALLOW_FORMAT_CHANGE 0x00000002
|
||||||
|
#define MA_SDL_AUDIO_ALLOW_CHANNELS_CHANGE 0x00000004
|
||||||
|
#define MA_SDL_AUDIO_ALLOW_ANY_CHANGE (MA_SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | MA_SDL_AUDIO_ALLOW_FORMAT_CHANGE | MA_SDL_AUDIO_ALLOW_CHANNELS_CHANGE)
|
||||||
|
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
#include <SDL2/SDL_audio.h>
|
||||||
|
|
||||||
|
typedef int (* MA_PFN_SDL_InitSubSystem)(ma_uint32 flags);
|
||||||
|
typedef void (* MA_PFN_SDL_QuitSubSystem)(ma_uint32 flags);
|
||||||
|
typedef int (* MA_PFN_SDL_GetNumAudioDevices)(int iscapture);
|
||||||
|
typedef const char* (* MA_PFN_SDL_GetAudioDeviceName)(int index, int iscapture);
|
||||||
|
typedef void (* MA_PFN_SDL_CloseAudioDevice)(SDL_AudioDeviceID dev);
|
||||||
|
typedef SDL_AudioDeviceID (* MA_PFN_SDL_OpenAudioDevice)(const char* device, int iscapture, const SDL_AudioSpec* desired, SDL_AudioSpec* obtained, int allowed_changes);
|
||||||
|
typedef void (* MA_PFN_SDL_PauseAudioDevice)(SDL_AudioDeviceID dev, int pause_on);
|
||||||
|
|
||||||
|
static SDL_AudioFormat ma_format_to_sdl(ma_format format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case ma_format_unknown: return 0;
|
||||||
|
case ma_format_u8: return MA_AUDIO_U8;
|
||||||
|
case ma_format_s16: return MA_AUDIO_S16;
|
||||||
|
case ma_format_s24: return MA_AUDIO_S32; // Closest match.
|
||||||
|
case ma_format_s32: return MA_AUDIO_S32;
|
||||||
|
case ma_format_f32: return MA_AUDIO_F32;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_format ma_format_from_sdl(SDL_AudioFormat format)
|
||||||
|
{
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case MA_AUDIO_U8: return ma_format_u8;
|
||||||
|
case MA_AUDIO_S16: return ma_format_s16;
|
||||||
|
case MA_AUDIO_S32: return ma_format_s32;
|
||||||
|
case MA_AUDIO_F32: return ma_format_f32;
|
||||||
|
default: return ma_format_unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_result ma_context_get_device_info__sdl(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_device_info* pDeviceInfo)
|
||||||
|
{
|
||||||
|
MA_ASSERT(pContext != NULL);
|
||||||
|
MA_ASSERT(deviceType == ma_device_type_playback);
|
||||||
|
|
||||||
|
pDeviceInfo->isDefault = MA_TRUE;
|
||||||
|
|
||||||
|
SDL_AudioSpec desiredSpec, obtainedSpec;
|
||||||
|
MA_ZERO_OBJECT(&desiredSpec);
|
||||||
|
|
||||||
|
SDL_AudioDeviceID tempDeviceID = ((MA_PFN_SDL_OpenAudioDevice)context_sdl.SDL_OpenAudioDevice)(NULL, 0, &desiredSpec, &obtainedSpec, MA_SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||||
|
((MA_PFN_SDL_CloseAudioDevice)context_sdl.SDL_CloseAudioDevice)(tempDeviceID);
|
||||||
|
|
||||||
|
ma_format format = ma_format_from_sdl(obtainedSpec.format);
|
||||||
|
if (format == ma_format_unknown) {
|
||||||
|
format = ma_format_f32;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDeviceInfo->nativeDataFormatCount = 0;
|
||||||
|
ma_device_info_add_native_data_format(pDeviceInfo, format, obtainedSpec.channels, obtainedSpec.freq, 0);
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ma_result ma_device_uninit__sdl(ma_device* pDevice)
|
||||||
|
{
|
||||||
|
MA_ASSERT(pDevice != NULL);
|
||||||
|
|
||||||
|
((MA_PFN_SDL_CloseAudioDevice)context_sdl.SDL_CloseAudioDevice)(device_sdl.deviceID);
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ma_audio_callback__sdl(void* pUserData, ma_uint8* pBuffer, int bufferSizeInBytes)
|
||||||
|
{
|
||||||
|
ma_device* pDevice = (ma_device*)pUserData;
|
||||||
|
MA_ASSERT(pDevice != NULL);
|
||||||
|
|
||||||
|
ma_uint32 bytesPerFrame = ma_get_bytes_per_frame(pDevice->playback.internalFormat, pDevice->playback.internalChannels);
|
||||||
|
ma_uint32 frameCount = (ma_uint32)bufferSizeInBytes / bytesPerFrame;
|
||||||
|
|
||||||
|
ma_device_handle_backend_data_callback(pDevice, pBuffer, NULL, frameCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_result ma_device_init__sdl(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture)
|
||||||
|
{
|
||||||
|
MA_ASSERT(pDevice != NULL);
|
||||||
|
MA_ASSERT(pConfig != NULL);
|
||||||
|
MA_ASSERT(pConfig->deviceType == ma_device_type_playback);
|
||||||
|
|
||||||
|
if (pDescriptorPlayback->sampleRate == 0) {
|
||||||
|
pDescriptorPlayback->sampleRate = MA_DEFAULT_SAMPLE_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pDescriptorPlayback->periodSizeInFrames = pDescriptorPlayback->periodCount * ma_calculate_buffer_size_in_frames_from_descriptor(pDescriptorPlayback, pDescriptorPlayback->sampleRate, pConfig->performanceProfile);
|
||||||
|
|
||||||
|
/* SDL wants the buffer size to be a power of 2 for some reason. */
|
||||||
|
if (pDescriptorPlayback->periodSizeInFrames > 32768) {
|
||||||
|
pDescriptorPlayback->periodSizeInFrames = 32768;
|
||||||
|
} else {
|
||||||
|
pDescriptorPlayback->periodSizeInFrames = ma_next_power_of_2(pDescriptorPlayback->periodSizeInFrames);
|
||||||
|
}
|
||||||
|
|
||||||
|
MA_ASSERT(pDescriptorPlayback->periodSizeInFrames <= 32768);
|
||||||
|
|
||||||
|
/* We now have enough information to set up the device. */
|
||||||
|
SDL_AudioSpec desiredSpec, obtainedSpec;
|
||||||
|
MA_ZERO_OBJECT(&desiredSpec);
|
||||||
|
desiredSpec.freq = (int)pDescriptorPlayback->sampleRate;
|
||||||
|
desiredSpec.format = ma_format_to_sdl(pDescriptorPlayback->format);
|
||||||
|
desiredSpec.channels = (ma_uint8)pDescriptorPlayback->channels;
|
||||||
|
desiredSpec.samples = (ma_uint16)pDescriptorPlayback->periodSizeInFrames;
|
||||||
|
desiredSpec.callback = ma_audio_callback__sdl;
|
||||||
|
desiredSpec.userdata = pDevice;
|
||||||
|
|
||||||
|
/* We'll fall back to f32 if we don't have an appropriate mapping between SDL and miniaudio. */
|
||||||
|
if (desiredSpec.format == ma_format_unknown) {
|
||||||
|
desiredSpec.format = MA_AUDIO_F32;
|
||||||
|
}
|
||||||
|
|
||||||
|
device_sdl.deviceID = ((MA_PFN_SDL_OpenAudioDevice)context_sdl.SDL_OpenAudioDevice)(NULL, 0, &desiredSpec, &obtainedSpec, MA_SDL_AUDIO_ALLOW_ANY_CHANGE);
|
||||||
|
|
||||||
|
/* The descriptor needs to be updated with our actual settings. */
|
||||||
|
pDescriptorPlayback->format = ma_format_from_sdl(obtainedSpec.format);
|
||||||
|
pDescriptorPlayback->channels = obtainedSpec.channels;
|
||||||
|
pDescriptorPlayback->sampleRate = (ma_uint32)obtainedSpec.freq;
|
||||||
|
ma_channel_map_init_standard(ma_standard_channel_map_default, pDescriptorPlayback->channelMap, ma_countof(pDescriptorPlayback->channelMap), pDescriptorPlayback->channels);
|
||||||
|
pDescriptorPlayback->periodSizeInFrames = obtainedSpec.samples;
|
||||||
|
pDescriptorPlayback->periodCount = 1; /* SDL doesn't use the notion of period counts, so just set to 1. */
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_result ma_device_start__sdl(ma_device* pDevice)
|
||||||
|
{
|
||||||
|
MA_ASSERT(pDevice != NULL);
|
||||||
|
|
||||||
|
((MA_PFN_SDL_PauseAudioDevice)context_sdl.SDL_PauseAudioDevice)(device_sdl.deviceID, 0);
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_result ma_device_stop__sdl(ma_device* pDevice)
|
||||||
|
{
|
||||||
|
MA_ASSERT(pDevice != NULL);
|
||||||
|
|
||||||
|
((MA_PFN_SDL_PauseAudioDevice)context_sdl.SDL_PauseAudioDevice)(device_sdl.deviceID, 1);
|
||||||
|
|
||||||
|
ma_device__set_state(pDevice, ma_device_state_stopped);
|
||||||
|
ma_stop_proc onStop = pDevice->onStop;
|
||||||
|
if (onStop) {
|
||||||
|
onStop(pDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ma_result ma_context_uninit__sdl(ma_context* pContext)
|
||||||
|
{
|
||||||
|
MA_ASSERT(pContext != NULL);
|
||||||
|
|
||||||
|
((MA_PFN_SDL_QuitSubSystem)context_sdl.SDL_QuitSubSystem)(MA_SDL_INIT_AUDIO);
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ma_result ma_context_init__sdl(ma_context* pContext, const ma_context_config* pConfig, ma_backend_callbacks* pCallbacks)
|
||||||
|
{
|
||||||
|
MA_ASSERT(pContext != NULL);
|
||||||
|
|
||||||
|
(void)pConfig; /* Unused. */
|
||||||
|
|
||||||
|
context_sdl.SDL_InitSubSystem = (ma_proc)SDL_InitSubSystem;
|
||||||
|
context_sdl.SDL_QuitSubSystem = (ma_proc)SDL_QuitSubSystem;
|
||||||
|
context_sdl.SDL_GetNumAudioDevices = (ma_proc)SDL_GetNumAudioDevices;
|
||||||
|
context_sdl.SDL_GetAudioDeviceName = (ma_proc)SDL_GetAudioDeviceName;
|
||||||
|
context_sdl.SDL_CloseAudioDevice = (ma_proc)SDL_CloseAudioDevice;
|
||||||
|
context_sdl.SDL_OpenAudioDevice = (ma_proc)SDL_OpenAudioDevice;
|
||||||
|
context_sdl.SDL_PauseAudioDevice = (ma_proc)SDL_PauseAudioDevice;
|
||||||
|
|
||||||
|
int resultSDL = ((MA_PFN_SDL_InitSubSystem)context_sdl.SDL_InitSubSystem)(MA_SDL_INIT_AUDIO);
|
||||||
|
if (resultSDL != 0) {
|
||||||
|
return MA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCallbacks->onContextInit = ma_context_init__sdl;
|
||||||
|
pCallbacks->onContextUninit = ma_context_uninit__sdl;
|
||||||
|
pCallbacks->onContextEnumerateDevices = NULL;
|
||||||
|
pCallbacks->onContextGetDeviceInfo = ma_context_get_device_info__sdl;
|
||||||
|
pCallbacks->onDeviceInit = ma_device_init__sdl;
|
||||||
|
pCallbacks->onDeviceUninit = ma_device_uninit__sdl;
|
||||||
|
pCallbacks->onDeviceStart = ma_device_start__sdl;
|
||||||
|
pCallbacks->onDeviceStop = ma_device_stop__sdl;
|
||||||
|
pCallbacks->onDeviceRead = NULL;
|
||||||
|
pCallbacks->onDeviceWrite = NULL;
|
||||||
|
pCallbacks->onDeviceDataLoop = NULL;
|
||||||
|
|
||||||
|
return MA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
@ -101,47 +101,47 @@ extern "C" { // Prevents name mangling of functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Linear Easing functions
|
// Linear Easing functions
|
||||||
EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); }
|
EASEDEF float EaseLinearNone(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear
|
||||||
EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); }
|
EASEDEF float EaseLinearIn(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear In
|
||||||
EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); }
|
EASEDEF float EaseLinearOut(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear Out
|
||||||
EASEDEF float EaseLinearInOut(float t,float b, float c, float d) { return (c*t/d + b); }
|
EASEDEF float EaseLinearInOut(float t, float b, float c, float d) { return (c*t/d + b); } // Ease: Linear In Out
|
||||||
|
|
||||||
// Sine Easing functions
|
// Sine Easing functions
|
||||||
EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cosf(t/d*(PI/2.0f)) + c + b); }
|
EASEDEF float EaseSineIn(float t, float b, float c, float d) { return (-c*cosf(t/d*(PI/2.0f)) + c + b); } // Ease: Sine In
|
||||||
EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sinf(t/d*(PI/2.0f)) + b); }
|
EASEDEF float EaseSineOut(float t, float b, float c, float d) { return (c*sinf(t/d*(PI/2.0f)) + b); } // Ease: Sine Out
|
||||||
EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2.0f*(cosf(PI*t/d) - 1.0f) + b); }
|
EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2.0f*(cosf(PI*t/d) - 1.0f) + b); } // Ease: Sine Out
|
||||||
|
|
||||||
// Circular Easing functions
|
// Circular Easing functions
|
||||||
EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrtf(1.0f - t*t) - 1.0f) + b); }
|
EASEDEF float EaseCircIn(float t, float b, float c, float d) { t /= d; return (-c*(sqrtf(1.0f - t*t) - 1.0f) + b); } // Ease: Circular In
|
||||||
EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*sqrtf(1.0f - t*t) + b); }
|
EASEDEF float EaseCircOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*sqrtf(1.0f - t*t) + b); } // Ease: Circular Out
|
||||||
EASEDEF float EaseCircInOut(float t, float b, float c, float d)
|
EASEDEF float EaseCircInOut(float t, float b, float c, float d) // Ease: Circular In Out
|
||||||
{
|
{
|
||||||
if ((t/=d/2.0f) < 1.0f) return (-c/2.0f*(sqrtf(1.0f - t*t) - 1.0f) + b);
|
if ((t/=d/2.0f) < 1.0f) return (-c/2.0f*(sqrtf(1.0f - t*t) - 1.0f) + b);
|
||||||
t -= 2.0f; return (c/2.0f*(sqrtf(1.0f - t*t) + 1.0f) + b);
|
t -= 2.0f; return (c/2.0f*(sqrtf(1.0f - t*t) + 1.0f) + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cubic Easing functions
|
// Cubic Easing functions
|
||||||
EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); }
|
EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + b); } // Ease: Cubic In
|
||||||
EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*(t*t*t + 1.0f) + b); }
|
EASEDEF float EaseCubicOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*(t*t*t + 1.0f) + b); } // Ease: Cubic Out
|
||||||
EASEDEF float EaseCubicInOut(float t, float b, float c, float d)
|
EASEDEF float EaseCubicInOut(float t, float b, float c, float d) // Ease: Cubic In Out
|
||||||
{
|
{
|
||||||
if ((t/=d/2.0f) < 1.0f) return (c/2.0f*t*t*t + b);
|
if ((t/=d/2.0f) < 1.0f) return (c/2.0f*t*t*t + b);
|
||||||
t -= 2.0f; return (c/2.0f*(t*t*t + 2.0f) + b);
|
t -= 2.0f; return (c/2.0f*(t*t*t + 2.0f) + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quadratic Easing functions
|
// Quadratic Easing functions
|
||||||
EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); }
|
EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); } // Ease: Quadratic In
|
||||||
EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2.0f) + b); }
|
EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2.0f) + b); } // Ease: Quadratic Out
|
||||||
EASEDEF float EaseQuadInOut(float t, float b, float c, float d)
|
EASEDEF float EaseQuadInOut(float t, float b, float c, float d) // Ease: Quadratic In Out
|
||||||
{
|
{
|
||||||
if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b);
|
if ((t/=d/2) < 1) return (((c/2)*(t*t)) + b);
|
||||||
return (-c/2.0f*(((t - 1.0f)*(t - 3.0f)) - 1.0f) + b);
|
return (-c/2.0f*(((t - 1.0f)*(t - 3.0f)) - 1.0f) + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exponential Easing functions
|
// Exponential Easing functions
|
||||||
EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0.0f) ? b : (c*powf(2.0f, 10.0f*(t/d - 1.0f)) + b); }
|
EASEDEF float EaseExpoIn(float t, float b, float c, float d) { return (t == 0.0f) ? b : (c*powf(2.0f, 10.0f*(t/d - 1.0f)) + b); } // Ease: Exponential In
|
||||||
EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-powf(2.0f, -10.0f*t/d) + 1.0f) + b); }
|
EASEDEF float EaseExpoOut(float t, float b, float c, float d) { return (t == d) ? (b + c) : (c*(-powf(2.0f, -10.0f*t/d) + 1.0f) + b); } // Ease: Exponential Out
|
||||||
EASEDEF float EaseExpoInOut(float t, float b, float c, float d)
|
EASEDEF float EaseExpoInOut(float t, float b, float c, float d) // Ease: Exponential In Out
|
||||||
{
|
{
|
||||||
if (t == 0.0f) return b;
|
if (t == 0.0f) return b;
|
||||||
if (t == d) return (b + c);
|
if (t == d) return (b + c);
|
||||||
|
|
@ -151,21 +151,21 @@ EASEDEF float EaseExpoInOut(float t, float b, float c, float d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Back Easing functions
|
// Back Easing functions
|
||||||
EASEDEF float EaseBackIn(float t, float b, float c, float d)
|
EASEDEF float EaseBackIn(float t, float b, float c, float d) // Ease: Back In
|
||||||
{
|
{
|
||||||
float s = 1.70158f;
|
float s = 1.70158f;
|
||||||
float postFix = t/=d;
|
float postFix = t/=d;
|
||||||
return (c*(postFix)*t*((s + 1.0f)*t - s) + b);
|
return (c*(postFix)*t*((s + 1.0f)*t - s) + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
EASEDEF float EaseBackOut(float t, float b, float c, float d)
|
EASEDEF float EaseBackOut(float t, float b, float c, float d) // Ease: Back Out
|
||||||
{
|
{
|
||||||
float s = 1.70158f;
|
float s = 1.70158f;
|
||||||
t = t/d - 1.0f;
|
t = t/d - 1.0f;
|
||||||
return (c*(t*t*((s + 1.0f)*t + s) + 1.0f) + b);
|
return (c*(t*t*((s + 1.0f)*t + s) + 1.0f) + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
EASEDEF float EaseBackInOut(float t, float b, float c, float d)
|
EASEDEF float EaseBackInOut(float t, float b, float c, float d) // Ease: Back In Out
|
||||||
{
|
{
|
||||||
float s = 1.70158f;
|
float s = 1.70158f;
|
||||||
if ((t/=d/2.0f) < 1.0f)
|
if ((t/=d/2.0f) < 1.0f)
|
||||||
|
|
@ -180,7 +180,7 @@ EASEDEF float EaseBackInOut(float t, float b, float c, float d)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bounce Easing functions
|
// Bounce Easing functions
|
||||||
EASEDEF float EaseBounceOut(float t, float b, float c, float d)
|
EASEDEF float EaseBounceOut(float t, float b, float c, float d) // Ease: Bounce Out
|
||||||
{
|
{
|
||||||
if ((t/=d) < (1.0f/2.75f))
|
if ((t/=d) < (1.0f/2.75f))
|
||||||
{
|
{
|
||||||
|
|
@ -203,15 +203,15 @@ EASEDEF float EaseBounceOut(float t, float b, float c, float d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d - t, 0.0f, c, d) + b); }
|
EASEDEF float EaseBounceIn(float t, float b, float c, float d) { return (c - EaseBounceOut(d - t, 0.0f, c, d) + b); } // Ease: Bounce In
|
||||||
EASEDEF float EaseBounceInOut(float t, float b, float c, float d)
|
EASEDEF float EaseBounceInOut(float t, float b, float c, float d) // Ease: Bounce In Out
|
||||||
{
|
{
|
||||||
if (t < d/2.0f) return (EaseBounceIn(t*2.0f, 0.0f, c, d)*0.5f + b);
|
if (t < d/2.0f) return (EaseBounceIn(t*2.0f, 0.0f, c, d)*0.5f + b);
|
||||||
else return (EaseBounceOut(t*2.0f - d, 0.0f, c, d)*0.5f + c*0.5f + b);
|
else return (EaseBounceOut(t*2.0f - d, 0.0f, c, d)*0.5f + c*0.5f + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Elastic Easing functions
|
// Elastic Easing functions
|
||||||
EASEDEF float EaseElasticIn(float t, float b, float c, float d)
|
EASEDEF float EaseElasticIn(float t, float b, float c, float d) // Ease: Elastic In
|
||||||
{
|
{
|
||||||
if (t == 0.0f) return b;
|
if (t == 0.0f) return b;
|
||||||
if ((t/=d) == 1.0f) return (b + c);
|
if ((t/=d) == 1.0f) return (b + c);
|
||||||
|
|
@ -224,7 +224,7 @@ EASEDEF float EaseElasticIn(float t, float b, float c, float d)
|
||||||
return (-(postFix*sinf((t*d-s)*(2.0f*PI)/p )) + b);
|
return (-(postFix*sinf((t*d-s)*(2.0f*PI)/p )) + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
EASEDEF float EaseElasticOut(float t, float b, float c, float d)
|
EASEDEF float EaseElasticOut(float t, float b, float c, float d) // Ease: Elastic Out
|
||||||
{
|
{
|
||||||
if (t == 0.0f) return b;
|
if (t == 0.0f) return b;
|
||||||
if ((t/=d) == 1.0f) return (b + c);
|
if ((t/=d) == 1.0f) return (b + c);
|
||||||
|
|
@ -236,7 +236,7 @@ EASEDEF float EaseElasticOut(float t, float b, float c, float d)
|
||||||
return (a*powf(2.0f,-10.0f*t)*sinf((t*d-s)*(2.0f*PI)/p) + c + b);
|
return (a*powf(2.0f,-10.0f*t)*sinf((t*d-s)*(2.0f*PI)/p) + c + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
EASEDEF float EaseElasticInOut(float t, float b, float c, float d)
|
EASEDEF float EaseElasticInOut(float t, float b, float c, float d) // Ease: Elastic In Out
|
||||||
{
|
{
|
||||||
if (t == 0.0f) return b;
|
if (t == 0.0f) return b;
|
||||||
if ((t/=d/2.0f) == 2.0f) return (b + c);
|
if ((t/=d/2.0f) == 2.0f) return (b + c);
|
||||||
|
|
|
||||||
|
|
@ -1999,7 +1999,6 @@ bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
||||||
{
|
{
|
||||||
keyCount--;
|
keyCount--;
|
||||||
text[keyCount] = '\0';
|
text[keyCount] = '\0';
|
||||||
if (keyCount < 0) keyCount = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2177,7 +2176,6 @@ bool GuiValueBox(Rectangle bounds, const char *text, int *value, int minValue, i
|
||||||
{
|
{
|
||||||
keyCount--;
|
keyCount--;
|
||||||
textValue[keyCount] = '\0';
|
textValue[keyCount] = '\0';
|
||||||
if (keyCount < 0) keyCount = 0;
|
|
||||||
valueHasChanged = true;
|
valueHasChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
190
src/raudio.c
190
src/raudio.c
|
|
@ -163,6 +163,11 @@ typedef struct tagBITMAPINFOHEADER {
|
||||||
#define MA_MALLOC RL_MALLOC
|
#define MA_MALLOC RL_MALLOC
|
||||||
#define MA_FREE RL_FREE
|
#define MA_FREE RL_FREE
|
||||||
|
|
||||||
|
#if defined(PLATFORM_NX)
|
||||||
|
#define MA_ENABLE_ONLY_SPECIFIC_BACKENDS
|
||||||
|
#define MA_ENABLE_CUSTOM
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MA_NO_JACK
|
#define MA_NO_JACK
|
||||||
#define MA_NO_WAV
|
#define MA_NO_WAV
|
||||||
#define MA_NO_FLAC
|
#define MA_NO_FLAC
|
||||||
|
|
@ -170,6 +175,9 @@ typedef struct tagBITMAPINFOHEADER {
|
||||||
#define MINIAUDIO_IMPLEMENTATION
|
#define MINIAUDIO_IMPLEMENTATION
|
||||||
//#define MA_DEBUG_OUTPUT
|
//#define MA_DEBUG_OUTPUT
|
||||||
#include "external/miniaudio.h" // Audio device initialization and management
|
#include "external/miniaudio.h" // Audio device initialization and management
|
||||||
|
#if defined(PLATFORM_NX)
|
||||||
|
#include "external/miniaudio_sdl.h"
|
||||||
|
#endif
|
||||||
#undef PlaySound // Win32 API: windows.h > mmsystem.h defines PlaySound macro
|
#undef PlaySound // Win32 API: windows.h > mmsystem.h defines PlaySound macro
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: malloc(), free()
|
#include <stdlib.h> // Required for: malloc(), free()
|
||||||
|
|
@ -247,10 +255,6 @@ typedef struct tagBITMAPINFOHEADER {
|
||||||
#include "external/dr_flac.h" // FLAC loading functions
|
#include "external/dr_flac.h" // FLAC loading functions
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#undef bool
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Defines and Macros
|
// Defines and Macros
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -311,10 +315,13 @@ typedef enum {
|
||||||
AUDIO_BUFFER_USAGE_STREAM
|
AUDIO_BUFFER_USAGE_STREAM
|
||||||
} AudioBufferUsage;
|
} AudioBufferUsage;
|
||||||
|
|
||||||
// Audio buffer structure
|
// Audio buffer struct
|
||||||
struct rAudioBuffer {
|
struct rAudioBuffer {
|
||||||
ma_data_converter converter; // Audio data converter
|
ma_data_converter converter; // Audio data converter
|
||||||
|
|
||||||
|
AudioCallback callback; // Audio buffer callback for buffer filling on audio threads
|
||||||
|
rAudioProcessor *processor; // Audio processor
|
||||||
|
|
||||||
float volume; // Audio buffer volume
|
float volume; // Audio buffer volume
|
||||||
float pitch; // Audio buffer pitch
|
float pitch; // Audio buffer pitch
|
||||||
float pan; // Audio buffer pan (0.0f to 1.0f)
|
float pan; // Audio buffer pan (0.0f to 1.0f)
|
||||||
|
|
@ -335,6 +342,14 @@ struct rAudioBuffer {
|
||||||
rAudioBuffer *prev; // Previous audio buffer on the list
|
rAudioBuffer *prev; // Previous audio buffer on the list
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Audio processor struct
|
||||||
|
// NOTE: Useful to apply effects to an AudioBuffer
|
||||||
|
struct rAudioProcessor {
|
||||||
|
AudioCallback process; // Processor callback function
|
||||||
|
rAudioProcessor *next; // Next audio processor on the list
|
||||||
|
rAudioProcessor *prev; // Previous audio processor on the list
|
||||||
|
};
|
||||||
|
|
||||||
#define AudioBuffer rAudioBuffer // HACK: To avoid CoreAudio (macOS) symbol collision
|
#define AudioBuffer rAudioBuffer // HACK: To avoid CoreAudio (macOS) symbol collision
|
||||||
|
|
||||||
// Audio data context
|
// Audio data context
|
||||||
|
|
@ -372,7 +387,7 @@ static AudioData AUDIO = { // Global AUDIO context
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Declaration
|
// Module specific Functions Declaration
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message);
|
static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage);
|
||||||
static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount);
|
static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const void *pFramesInput, ma_uint32 frameCount);
|
||||||
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer);
|
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer);
|
||||||
|
|
||||||
|
|
@ -411,9 +426,17 @@ void InitAudioDevice(void)
|
||||||
{
|
{
|
||||||
// Init audio context
|
// Init audio context
|
||||||
ma_context_config ctxConfig = ma_context_config_init();
|
ma_context_config ctxConfig = ma_context_config_init();
|
||||||
ctxConfig.logCallback = OnLog;
|
ma_log_callback_init(OnLog, NULL);
|
||||||
|
|
||||||
|
#if defined(PLATFORM_NX)
|
||||||
|
ma_backend backends[] = {
|
||||||
|
ma_backend_custom
|
||||||
|
};
|
||||||
|
ctxConfig.custom.onContextInit = ma_context_init__sdl;
|
||||||
|
ma_result result = ma_context_init(backends, sizeof(backends)/sizeof(backends[0]), &ctxConfig, &AUDIO.System.context);
|
||||||
|
#else
|
||||||
ma_result result = ma_context_init(NULL, 0, &ctxConfig, &AUDIO.System.context);
|
ma_result result = ma_context_init(NULL, 0, &ctxConfig, &AUDIO.System.context);
|
||||||
|
#endif
|
||||||
if (result != MA_SUCCESS)
|
if (result != MA_SUCCESS)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize context");
|
TRACELOG(LOG_WARNING, "AUDIO: Failed to initialize context");
|
||||||
|
|
@ -465,8 +488,7 @@ void InitAudioDevice(void)
|
||||||
// Init dummy audio buffers pool for multichannel sound playing
|
// Init dummy audio buffers pool for multichannel sound playing
|
||||||
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
|
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
|
||||||
{
|
{
|
||||||
// WARNING: An empty audio buffer is created (data = 0)
|
// WARNING: An empty audio buffer is created (data = 0) and added to list, AudioBuffer data is filled on PlaySoundMulti()
|
||||||
// AudioBuffer data just points to loaded sound data
|
|
||||||
AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
|
AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -492,7 +514,7 @@ void CloseAudioDevice(void)
|
||||||
//UnloadAudioBuffer(AUDIO.MultiChannel.pool[i]);
|
//UnloadAudioBuffer(AUDIO.MultiChannel.pool[i]);
|
||||||
if (AUDIO.MultiChannel.pool[i] != NULL)
|
if (AUDIO.MultiChannel.pool[i] != NULL)
|
||||||
{
|
{
|
||||||
ma_data_converter_uninit(&AUDIO.MultiChannel.pool[i]->converter);
|
ma_data_converter_uninit(&AUDIO.MultiChannel.pool[i]->converter, NULL);
|
||||||
UntrackAudioBuffer(AUDIO.MultiChannel.pool[i]);
|
UntrackAudioBuffer(AUDIO.MultiChannel.pool[i]);
|
||||||
//RL_FREE(buffer->data); // Already unloaded by UnloadSound()
|
//RL_FREE(buffer->data); // Already unloaded by UnloadSound()
|
||||||
RL_FREE(AUDIO.MultiChannel.pool[i]);
|
RL_FREE(AUDIO.MultiChannel.pool[i]);
|
||||||
|
|
@ -541,9 +563,9 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
|
||||||
|
|
||||||
// Audio data runs through a format converter
|
// Audio data runs through a format converter
|
||||||
ma_data_converter_config converterConfig = ma_data_converter_config_init(format, AUDIO_DEVICE_FORMAT, channels, AUDIO_DEVICE_CHANNELS, sampleRate, AUDIO.System.device.sampleRate);
|
ma_data_converter_config converterConfig = ma_data_converter_config_init(format, AUDIO_DEVICE_FORMAT, channels, AUDIO_DEVICE_CHANNELS, sampleRate, AUDIO.System.device.sampleRate);
|
||||||
converterConfig.resampling.allowDynamicSampleRate = true; // Pitch shifting
|
converterConfig.allowDynamicSampleRate = true;
|
||||||
|
|
||||||
ma_result result = ma_data_converter_init(&converterConfig, &audioBuffer->converter);
|
ma_result result = ma_data_converter_init(&converterConfig, NULL, &audioBuffer->converter);
|
||||||
|
|
||||||
if (result != MA_SUCCESS)
|
if (result != MA_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|
@ -557,9 +579,13 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
|
||||||
audioBuffer->pitch = 1.0f;
|
audioBuffer->pitch = 1.0f;
|
||||||
audioBuffer->pan = 0.5f;
|
audioBuffer->pan = 0.5f;
|
||||||
|
|
||||||
|
audioBuffer->callback = NULL;
|
||||||
|
audioBuffer->processor = NULL;
|
||||||
|
|
||||||
audioBuffer->playing = false;
|
audioBuffer->playing = false;
|
||||||
audioBuffer->paused = false;
|
audioBuffer->paused = false;
|
||||||
audioBuffer->looping = false;
|
audioBuffer->looping = false;
|
||||||
|
|
||||||
audioBuffer->usage = usage;
|
audioBuffer->usage = usage;
|
||||||
audioBuffer->frameCursorPos = 0;
|
audioBuffer->frameCursorPos = 0;
|
||||||
audioBuffer->sizeInFrames = sizeInFrames;
|
audioBuffer->sizeInFrames = sizeInFrames;
|
||||||
|
|
@ -580,7 +606,7 @@ void UnloadAudioBuffer(AudioBuffer *buffer)
|
||||||
{
|
{
|
||||||
if (buffer != NULL)
|
if (buffer != NULL)
|
||||||
{
|
{
|
||||||
ma_data_converter_uninit(&buffer->converter);
|
ma_data_converter_uninit(&buffer->converter, NULL);
|
||||||
UntrackAudioBuffer(buffer);
|
UntrackAudioBuffer(buffer);
|
||||||
RL_FREE(buffer->data);
|
RL_FREE(buffer->data);
|
||||||
RL_FREE(buffer);
|
RL_FREE(buffer);
|
||||||
|
|
@ -654,8 +680,8 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
|
||||||
// Note that this changes the duration of the sound:
|
// Note that this changes the duration of the sound:
|
||||||
// - higher pitches will make the sound faster
|
// - higher pitches will make the sound faster
|
||||||
// - lower pitches make it slower
|
// - lower pitches make it slower
|
||||||
ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.config.sampleRateOut/pitch);
|
ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.sampleRateOut/pitch);
|
||||||
ma_data_converter_set_rate(&buffer->converter, buffer->converter.config.sampleRateIn, outputSampleRate);
|
ma_data_converter_set_rate(&buffer->converter, buffer->converter.sampleRateIn, outputSampleRate);
|
||||||
|
|
||||||
buffer->pitch = pitch;
|
buffer->pitch = pitch;
|
||||||
}
|
}
|
||||||
|
|
@ -894,7 +920,7 @@ void UpdateSound(Sound sound, const void *data, int sampleCount)
|
||||||
StopAudioBuffer(sound.stream.buffer);
|
StopAudioBuffer(sound.stream.buffer);
|
||||||
|
|
||||||
// TODO: May want to lock/unlock this since this data buffer is read at mixing time
|
// TODO: May want to lock/unlock this since this data buffer is read at mixing time
|
||||||
memcpy(sound.stream.buffer->data, data, sampleCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.config.formatIn, sound.stream.buffer->converter.config.channelsIn));
|
memcpy(sound.stream.buffer->data, data, sampleCount*ma_get_bytes_per_frame(sound.stream.buffer->converter.formatIn, sound.stream.buffer->converter.channelsIn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1068,7 +1094,8 @@ void PlaySoundMulti(Sound sound)
|
||||||
AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[0] = false;
|
AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[0] = false;
|
||||||
AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[1] = false;
|
AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[1] = false;
|
||||||
AUDIO.MultiChannel.pool[index]->sizeInFrames = sound.stream.buffer->sizeInFrames;
|
AUDIO.MultiChannel.pool[index]->sizeInFrames = sound.stream.buffer->sizeInFrames;
|
||||||
AUDIO.MultiChannel.pool[index]->data = sound.stream.buffer->data;
|
|
||||||
|
AUDIO.MultiChannel.pool[index]->data = sound.stream.buffer->data; // Fill dummy track with data for playing
|
||||||
|
|
||||||
PlayAudioBuffer(AUDIO.MultiChannel.pool[index]);
|
PlayAudioBuffer(AUDIO.MultiChannel.pool[index]);
|
||||||
}
|
}
|
||||||
|
|
@ -1191,8 +1218,7 @@ Wave WaveCopy(Wave wave)
|
||||||
// NOTE: Security check in case of out-of-range
|
// NOTE: Security check in case of out-of-range
|
||||||
void WaveCrop(Wave *wave, int initSample, int finalSample)
|
void WaveCrop(Wave *wave, int initSample, int finalSample)
|
||||||
{
|
{
|
||||||
if ((initSample >= 0) && (initSample < finalSample) &&
|
if ((initSample >= 0) && (initSample < finalSample) && ((unsigned int)finalSample < (wave->frameCount*wave->channels)))
|
||||||
(finalSample > 0) && ((unsigned int)finalSample < (wave->frameCount*wave->channels)))
|
|
||||||
{
|
{
|
||||||
int sampleCount = finalSample - initSample;
|
int sampleCount = finalSample - initSample;
|
||||||
|
|
||||||
|
|
@ -1503,10 +1529,8 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
||||||
jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops
|
jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops
|
||||||
|
|
||||||
unsigned int bits = 32;
|
unsigned int bits = 32;
|
||||||
if (AUDIO_DEVICE_FORMAT == ma_format_s16)
|
if (AUDIO_DEVICE_FORMAT == ma_format_s16) bits = 16;
|
||||||
bits = 16;
|
else if (AUDIO_DEVICE_FORMAT == ma_format_u8) bits = 8;
|
||||||
else if (AUDIO_DEVICE_FORMAT == ma_format_u8)
|
|
||||||
bits = 8;
|
|
||||||
|
|
||||||
// NOTE: Only stereo is supported for XM
|
// NOTE: Only stereo is supported for XM
|
||||||
music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, 2);
|
music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, 2);
|
||||||
|
|
@ -1533,7 +1557,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
||||||
for (int i = 0; i < it; i++) newData[i] = data[i];
|
for (int i = 0; i < it; i++) newData[i] = data[i];
|
||||||
|
|
||||||
// Memory loaded version for jar_mod_load_file()
|
// Memory loaded version for jar_mod_load_file()
|
||||||
if (dataSize && dataSize < 32*1024*1024)
|
if (dataSize && (dataSize < 32*1024*1024))
|
||||||
{
|
{
|
||||||
ctxMod->modfilesize = dataSize;
|
ctxMod->modfilesize = dataSize;
|
||||||
ctxMod->modfile = newData;
|
ctxMod->modfile = newData;
|
||||||
|
|
@ -2028,22 +2052,86 @@ void SetAudioStreamBufferSizeDefault(int size)
|
||||||
AUDIO.Buffer.defaultSize = size;
|
AUDIO.Buffer.defaultSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Audio thread callback to request new data
|
||||||
|
void SetAudioStreamCallback(AudioStream stream, AudioCallback callback)
|
||||||
|
{
|
||||||
|
if (stream.buffer != NULL) stream.buffer->callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add processor to audio stream. Contrary to buffers, the order of processors is important.
|
||||||
|
// The new processor must be added at the end. As there aren't supposed to be a lot of processors attached to
|
||||||
|
// a given stream, we iterate through the list to find the end. That way we don't need a pointer to the last element.
|
||||||
|
void AttachAudioStreamProcessor(AudioStream stream, AudioCallback process)
|
||||||
|
{
|
||||||
|
ma_mutex_lock(&AUDIO.System.lock);
|
||||||
|
|
||||||
|
rAudioProcessor *processor = (rAudioProcessor *)RL_CALLOC(1, sizeof(rAudioProcessor));
|
||||||
|
processor->process = process;
|
||||||
|
|
||||||
|
rAudioProcessor *last = stream.buffer->processor;
|
||||||
|
|
||||||
|
while (last && last->next)
|
||||||
|
{
|
||||||
|
last = last->next;
|
||||||
|
}
|
||||||
|
if (last)
|
||||||
|
{
|
||||||
|
processor->prev = last;
|
||||||
|
last->next = processor;
|
||||||
|
}
|
||||||
|
else stream.buffer->processor = processor;
|
||||||
|
|
||||||
|
ma_mutex_unlock(&AUDIO.System.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetachAudioStreamProcessor(AudioStream stream, AudioCallback process)
|
||||||
|
{
|
||||||
|
ma_mutex_lock(&AUDIO.System.lock);
|
||||||
|
|
||||||
|
rAudioProcessor *processor = stream.buffer->processor;
|
||||||
|
|
||||||
|
while (processor)
|
||||||
|
{
|
||||||
|
rAudioProcessor *next = processor->next;
|
||||||
|
rAudioProcessor *prev = processor->prev;
|
||||||
|
|
||||||
|
if (processor->process == process)
|
||||||
|
{
|
||||||
|
if (stream.buffer->processor == processor) stream.buffer->processor = next;
|
||||||
|
if (prev) prev->next = next;
|
||||||
|
if (next) next->prev = prev;
|
||||||
|
|
||||||
|
RL_FREE(processor);
|
||||||
|
}
|
||||||
|
|
||||||
|
processor = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
ma_mutex_unlock(&AUDIO.System.lock);
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module specific Functions Definition
|
// Module specific Functions Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Log callback function
|
// Log callback function
|
||||||
static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel, const char *message)
|
static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage)
|
||||||
{
|
{
|
||||||
(void)pContext;
|
TRACELOG(LOG_WARNING, "miniaudio: %s", pMessage); // All log messages from miniaudio are errors
|
||||||
(void)pDevice;
|
|
||||||
|
|
||||||
TRACELOG(LOG_WARNING, "miniaudio: %s", message); // All log messages from miniaudio are errors
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads audio data from an AudioBuffer object in internal format.
|
// Reads audio data from an AudioBuffer object in internal format.
|
||||||
static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount)
|
static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, void *framesOut, ma_uint32 frameCount)
|
||||||
{
|
{
|
||||||
|
// Using audio buffer callback
|
||||||
|
if (audioBuffer->callback)
|
||||||
|
{
|
||||||
|
audioBuffer->callback(framesOut, frameCount);
|
||||||
|
audioBuffer->framesProcessed += frameCount;
|
||||||
|
|
||||||
|
return frameCount;
|
||||||
|
}
|
||||||
|
|
||||||
ma_uint32 subBufferSizeInFrames = (audioBuffer->sizeInFrames > 1)? audioBuffer->sizeInFrames/2 : audioBuffer->sizeInFrames;
|
ma_uint32 subBufferSizeInFrames = (audioBuffer->sizeInFrames > 1)? audioBuffer->sizeInFrames/2 : audioBuffer->sizeInFrames;
|
||||||
ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
|
ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
|
||||||
|
|
||||||
|
|
@ -2055,7 +2143,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
|
||||||
isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
|
isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
|
||||||
isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
|
isSubBufferProcessed[1] = audioBuffer->isSubBufferProcessed[1];
|
||||||
|
|
||||||
ma_uint32 frameSizeInBytes = ma_get_bytes_per_frame(audioBuffer->converter.config.formatIn, audioBuffer->converter.config.channelsIn);
|
ma_uint32 frameSizeInBytes = ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
|
||||||
|
|
||||||
// Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0
|
// Fill out every frame until we find a buffer that's marked as processed. Then fill the remainder with 0
|
||||||
ma_uint32 framesRead = 0;
|
ma_uint32 framesRead = 0;
|
||||||
|
|
@ -2135,20 +2223,21 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f
|
||||||
// detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output
|
// detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output
|
||||||
// frames. This can be achieved with ma_data_converter_get_required_input_frame_count().
|
// frames. This can be achieved with ma_data_converter_get_required_input_frame_count().
|
||||||
ma_uint8 inputBuffer[4096] = { 0 };
|
ma_uint8 inputBuffer[4096] = { 0 };
|
||||||
ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.config.formatIn, audioBuffer->converter.config.channelsIn);
|
ma_uint32 inputBufferFrameCap = sizeof(inputBuffer)/ma_get_bytes_per_frame(audioBuffer->converter.formatIn, audioBuffer->converter.channelsIn);
|
||||||
|
|
||||||
ma_uint32 totalOutputFramesProcessed = 0;
|
ma_uint32 totalOutputFramesProcessed = 0;
|
||||||
while (totalOutputFramesProcessed < frameCount)
|
while (totalOutputFramesProcessed < frameCount)
|
||||||
{
|
{
|
||||||
ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed;
|
ma_uint64 outputFramesToProcessThisIteration = frameCount - totalOutputFramesProcessed;
|
||||||
|
ma_uint64 inputFramesToProcessThisIteration = 0;
|
||||||
|
|
||||||
ma_uint64 inputFramesToProcessThisIteration = ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration);
|
ma_result result = ma_data_converter_get_required_input_frame_count(&audioBuffer->converter, outputFramesToProcessThisIteration, &inputFramesToProcessThisIteration);
|
||||||
if (inputFramesToProcessThisIteration > inputBufferFrameCap)
|
if (inputFramesToProcessThisIteration > inputBufferFrameCap)
|
||||||
{
|
{
|
||||||
inputFramesToProcessThisIteration = inputBufferFrameCap;
|
inputFramesToProcessThisIteration = inputBufferFrameCap;
|
||||||
}
|
}
|
||||||
|
|
||||||
float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.config.channelsOut);
|
float *runningFramesOut = framesOut + (totalOutputFramesProcessed*audioBuffer->converter.channelsOut);
|
||||||
|
|
||||||
/* At this point we can convert the data to our mixing format. */
|
/* At this point we can convert the data to our mixing format. */
|
||||||
ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */
|
ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */
|
||||||
|
|
@ -2217,6 +2306,14 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
|
||||||
float *framesOut = (float *)pFramesOut + (framesRead*AUDIO.System.device.playback.channels);
|
float *framesOut = (float *)pFramesOut + (framesRead*AUDIO.System.device.playback.channels);
|
||||||
float *framesIn = tempBuffer;
|
float *framesIn = tempBuffer;
|
||||||
|
|
||||||
|
// Apply processors chain if defined
|
||||||
|
rAudioProcessor *processor = audioBuffer->processor;
|
||||||
|
while (processor)
|
||||||
|
{
|
||||||
|
processor->process(framesIn, framesJustRead);
|
||||||
|
processor = processor->next;
|
||||||
|
}
|
||||||
|
|
||||||
MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer);
|
MixAudioFrames(framesOut, framesIn, framesJustRead, audioBuffer);
|
||||||
|
|
||||||
framesToRead -= framesJustRead;
|
framesToRead -= framesJustRead;
|
||||||
|
|
@ -2257,41 +2354,44 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
|
||||||
ma_mutex_unlock(&AUDIO.System.lock);
|
ma_mutex_unlock(&AUDIO.System.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
|
// Main mixing function, pretty simple in this project, just an accumulation
|
||||||
// NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
|
// NOTE: framesOut is both an input and an output, it is initially filled with zeros outside of this function
|
||||||
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer)
|
static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer)
|
||||||
{
|
{
|
||||||
const float localVolume = buffer->volume;
|
const float localVolume = buffer->volume;
|
||||||
|
const ma_uint32 channels = AUDIO.System.device.playback.channels;
|
||||||
|
|
||||||
const ma_uint32 nChannels = AUDIO.System.device.playback.channels;
|
if (channels == 2) // We consider panning
|
||||||
if (nChannels == 2)
|
|
||||||
{
|
{
|
||||||
const float left = buffer->pan;
|
const float left = buffer->pan;
|
||||||
const float right = 1.0f - left;
|
const float right = 1.0f - left;
|
||||||
|
|
||||||
// fast sine approximation in [0..1] for pan law: y = 0.5f * x * (3 - x * x);
|
// Fast sine approximation in [0..1] for pan law: y = 0.5f*x*(3 - x*x);
|
||||||
const float levels[2] = { localVolume*0.5f*left*(3.0f - left*left), localVolume*0.5f*right*(3.0f - right*right) };
|
const float levels[2] = { localVolume*0.5f*left*(3.0f - left*left), localVolume*0.5f*right*(3.0f - right*right) };
|
||||||
|
|
||||||
float *frameOut = framesOut;
|
float *frameOut = framesOut;
|
||||||
const float *frameIn = framesIn;
|
const float *frameIn = framesIn;
|
||||||
for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
|
|
||||||
|
for (ma_uint32 frame = 0; frame < frameCount; frame++)
|
||||||
{
|
{
|
||||||
frameOut[0] += (frameIn[0]*levels[0]);
|
frameOut[0] += (frameIn[0]*levels[0]);
|
||||||
frameOut[1] += (frameIn[1]*levels[1]);
|
frameOut[1] += (frameIn[1]*levels[1]);
|
||||||
|
|
||||||
frameOut += 2;
|
frameOut += 2;
|
||||||
frameIn += 2;
|
frameIn += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // pan is kinda meaningless
|
else // We do not consider panning
|
||||||
{
|
{
|
||||||
for (ma_uint32 iFrame = 0; iFrame < frameCount; ++iFrame)
|
for (ma_uint32 frame = 0; frame < frameCount; frame++)
|
||||||
{
|
{
|
||||||
for (ma_uint32 iChannel = 0; iChannel < nChannels; ++iChannel)
|
for (ma_uint32 c = 0; c < channels; c++)
|
||||||
{
|
{
|
||||||
float *frameOut = framesOut + (iFrame * nChannels);
|
float *frameOut = framesOut + (frame*channels);
|
||||||
const float *frameIn = framesIn + (iFrame * nChannels);
|
const float *frameIn = framesIn + (frame*channels);
|
||||||
|
|
||||||
frameOut[iChannel] += (frameIn[iChannel] * localVolume);
|
// Output accumulates input multiplied by volume to provided output (usually 0)
|
||||||
|
frameOut[c] += (frameIn[c]*localVolume);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
36
src/raylib.h
36
src/raylib.h
|
|
@ -33,8 +33,8 @@
|
||||||
*
|
*
|
||||||
* OPTIONAL DEPENDENCIES (included):
|
* OPTIONAL DEPENDENCIES (included):
|
||||||
* [rcore] msf_gif (Miles Fogle) for GIF recording
|
* [rcore] msf_gif (Miles Fogle) for GIF recording
|
||||||
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorythm
|
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm
|
||||||
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorythm
|
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm
|
||||||
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
|
* [rtextures] stb_image (Sean Barret) for images loading (BMP, TGA, PNG, JPEG, HDR...)
|
||||||
* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG)
|
* [rtextures] stb_image_write (Sean Barret) for image writing (BMP, TGA, PNG, JPG)
|
||||||
* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms
|
* [rtextures] stb_image_resize (Sean Barret) for image resizing algorithms
|
||||||
|
|
@ -177,10 +177,10 @@
|
||||||
// Structures Definition
|
// Structures Definition
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Boolean type
|
// Boolean type
|
||||||
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
|
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#elif !defined(__cplusplus) && !defined(bool)
|
#elif !defined(__cplusplus) && !defined(bool)
|
||||||
typedef enum bool { false, true } bool;
|
typedef enum bool { false = 0, true = !false } bool;
|
||||||
#define RL_BOOL_TYPE
|
#define RL_BOOL_TYPE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -322,7 +322,7 @@ typedef struct Mesh {
|
||||||
// Vertex attributes data
|
// Vertex attributes data
|
||||||
float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
|
float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
|
||||||
float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
|
float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
|
||||||
float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
|
float *texcoords2; // Vertex texture second coordinates (UV - 2 components per vertex) (shader-location = 5)
|
||||||
float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
|
float *normals; // Vertex normals (XYZ - 3 components per vertex) (shader-location = 2)
|
||||||
float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
|
float *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
|
||||||
unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
|
unsigned char *colors; // Vertex colors (RGBA - 4 components per vertex) (shader-location = 3)
|
||||||
|
|
@ -425,11 +425,15 @@ typedef struct Wave {
|
||||||
void *data; // Buffer data pointer
|
void *data; // Buffer data pointer
|
||||||
} Wave;
|
} Wave;
|
||||||
|
|
||||||
|
// Opaque structs declaration
|
||||||
|
// NOTE: Actual structs are defined internally in raudio module
|
||||||
typedef struct rAudioBuffer rAudioBuffer;
|
typedef struct rAudioBuffer rAudioBuffer;
|
||||||
|
typedef struct rAudioProcessor rAudioProcessor;
|
||||||
|
|
||||||
// AudioStream, custom audio stream
|
// AudioStream, custom audio stream
|
||||||
typedef struct AudioStream {
|
typedef struct AudioStream {
|
||||||
rAudioBuffer *buffer; // Pointer to internal data used by the audio system
|
rAudioBuffer *buffer; // Pointer to internal data used by the audio system
|
||||||
|
rAudioProcessor *processor; // Pointer to internal data processor, useful for audio effects
|
||||||
|
|
||||||
unsigned int sampleRate; // Frequency (samples per second)
|
unsigned int sampleRate; // Frequency (samples per second)
|
||||||
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
unsigned int sampleSize; // Bit depth (bits per sample): 8, 16, 32 (24 not supported)
|
||||||
|
|
@ -945,6 +949,8 @@ RLAPI Vector2 GetWindowScaleDPI(void); // Get window
|
||||||
RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the primary monitor
|
RLAPI const char *GetMonitorName(int monitor); // Get the human-readable, UTF-8 encoded name of the primary monitor
|
||||||
RLAPI void SetClipboardText(const char *text); // Set clipboard text content
|
RLAPI void SetClipboardText(const char *text); // Set clipboard text content
|
||||||
RLAPI const char *GetClipboardText(void); // Get clipboard text content
|
RLAPI const char *GetClipboardText(void); // Get clipboard text content
|
||||||
|
RLAPI void EnableEventWaiting(void); // Enable waiting for events on EndDrawing(), no automatic event polling
|
||||||
|
RLAPI void DisableEventWaiting(void); // Disable waiting for events on EndDrawing(), automatic events polling
|
||||||
|
|
||||||
// Custom frame control functions
|
// Custom frame control functions
|
||||||
// NOTE: Those functions are intended for advance users that want full control over the frame processing
|
// NOTE: Those functions are intended for advance users that want full control over the frame processing
|
||||||
|
|
@ -1036,6 +1042,7 @@ RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom
|
||||||
RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
|
RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
|
||||||
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
|
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
|
||||||
RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success
|
RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success
|
||||||
|
RLAPI bool ExportDataAsCode(const char *data, unsigned int size, const char *fileName); // Export data to code (.h), returns true on success
|
||||||
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
|
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
|
||||||
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
|
RLAPI void UnloadFileText(char *text); // Unload file text data allocated by LoadFileText()
|
||||||
RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
|
RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
|
||||||
|
|
@ -1050,19 +1057,19 @@ RLAPI const char *GetDirectoryPath(const char *filePath); // Get full pa
|
||||||
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
|
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string)
|
||||||
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
|
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
|
||||||
RLAPI const char *GetApplicationDirectory(void); // Get the directory if the running application (uses static string)
|
RLAPI const char *GetApplicationDirectory(void); // Get the directory if the running application (uses static string)
|
||||||
RLAPI char **GetDirectoryFiles(const char *dirPath, int *count); // Get filenames in a directory path (memory should be freed)
|
RLAPI char **GetDirectoryFiles(const char *dirPath, int *count); // Get filenames in a directory path (memory must be freed)
|
||||||
RLAPI void ClearDirectoryFiles(void); // Clear directory files paths buffers (free memory)
|
RLAPI void ClearDirectoryFiles(void); // Clear directory files paths buffers (free memory)
|
||||||
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success
|
RLAPI bool ChangeDirectory(const char *dir); // Change working directory, return true on success
|
||||||
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
|
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
|
||||||
RLAPI char **GetDroppedFiles(int *count); // Get dropped files names (memory should be freed)
|
RLAPI char **GetDroppedFiles(int *count); // Get dropped files names (memory must be freed)
|
||||||
RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer (free memory)
|
RLAPI void ClearDroppedFiles(void); // Clear dropped files paths buffer (free memory)
|
||||||
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
|
RLAPI long GetFileModTime(const char *fileName); // Get file modification time (last write time)
|
||||||
|
|
||||||
// Compression/Encoding functionality
|
// Compression/Encoding functionality
|
||||||
RLAPI unsigned char *CompressData(const unsigned char *data, int dataLength, int *compDataLength); // Compress data (DEFLATE algorithm)
|
RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree()
|
||||||
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataLength, int *dataLength); // Decompress data (DEFLATE algorithm)
|
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataLength, int *outputLength); // Encode data to Base64 string
|
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); // Encode data to Base64 string, memory must be MemFree()
|
||||||
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputLength); // Decode Base64 string data
|
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); // Decode Base64 string data, memory must be MemFree()
|
||||||
|
|
||||||
// Persistent storage management
|
// Persistent storage management
|
||||||
RLAPI bool SaveStorageValue(unsigned int position, int value); // Save integer value to storage file (to defined position), returns true on success
|
RLAPI bool SaveStorageValue(unsigned int position, int value); // Save integer value to storage file (to defined position), returns true on success
|
||||||
|
|
@ -1331,7 +1338,6 @@ RLAPI void UnloadFontData(GlyphInfo *chars, int glyphCount);
|
||||||
RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM)
|
RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM)
|
||||||
RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success
|
RLAPI bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success
|
||||||
|
|
||||||
|
|
||||||
// Text drawing functions
|
// Text drawing functions
|
||||||
RLAPI void DrawFPS(int posX, int posY); // Draw current FPS
|
RLAPI void DrawFPS(int posX, int posY); // Draw current FPS
|
||||||
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
|
RLAPI void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
|
||||||
|
|
@ -1465,7 +1471,6 @@ RLAPI bool CheckCollisionBoxes(BoundingBox box1, BoundingBox box2);
|
||||||
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
|
RLAPI bool CheckCollisionBoxSphere(BoundingBox box, Vector3 center, float radius); // Check collision between box and sphere
|
||||||
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
|
RLAPI RayCollision GetRayCollisionSphere(Ray ray, Vector3 center, float radius); // Get collision info between ray and sphere
|
||||||
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
|
RLAPI RayCollision GetRayCollisionBox(Ray ray, BoundingBox box); // Get collision info between ray and box
|
||||||
RLAPI RayCollision GetRayCollisionModel(Ray ray, Model model); // Get collision info between ray and model
|
|
||||||
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
|
RLAPI RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform); // Get collision info between ray and mesh
|
||||||
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
RLAPI RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
||||||
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
|
RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4); // Get collision info between ray and quad
|
||||||
|
|
@ -1473,6 +1478,7 @@ RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Audio Loading and Playing Functions (Module: audio)
|
// Audio Loading and Playing Functions (Module: audio)
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
|
typedef void (*AudioCallback)(void *bufferData, unsigned int frames);
|
||||||
|
|
||||||
// Audio device management functions
|
// Audio device management functions
|
||||||
RLAPI void InitAudioDevice(void); // Initialize audio device and context
|
RLAPI void InitAudioDevice(void); // Initialize audio device and context
|
||||||
|
|
@ -1540,6 +1546,10 @@ RLAPI void SetAudioStreamVolume(AudioStream stream, float volume); // Set vol
|
||||||
RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
|
RLAPI void SetAudioStreamPitch(AudioStream stream, float pitch); // Set pitch for audio stream (1.0 is base level)
|
||||||
RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered)
|
RLAPI void SetAudioStreamPan(AudioStream stream, float pan); // Set pan for audio stream (0.5 is centered)
|
||||||
RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
|
RLAPI void SetAudioStreamBufferSizeDefault(int size); // Default size for new audio streams
|
||||||
|
RLAPI void SetAudioStreamCallback(AudioStream stream, AudioCallback callback); // Audio thread callback to request new data
|
||||||
|
|
||||||
|
RLAPI void AttachAudioStreamProcessor(AudioStream stream, AudioCallback processor);
|
||||||
|
RLAPI void DetachAudioStreamProcessor(AudioStream stream, AudioCallback processor);
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
228
src/raymath.h
228
src/raymath.h
|
|
@ -18,7 +18,7 @@
|
||||||
* - Functions are always self-contained, no function use another raymath function inside,
|
* - Functions are always self-contained, no function use another raymath function inside,
|
||||||
* required code is directly re-implemented inside
|
* required code is directly re-implemented inside
|
||||||
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
* - Functions input parameters are always received by value (2 unavoidable exceptions)
|
||||||
* - Functions use always a "result" anmed variable for return
|
* - Functions use always a "result" variable for return
|
||||||
* - Functions are always defined inline
|
* - Functions are always defined inline
|
||||||
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
|
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
|
||||||
*
|
*
|
||||||
|
|
@ -77,6 +77,10 @@
|
||||||
#define PI 3.14159265358979323846f
|
#define PI 3.14159265358979323846f
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef EPSILON
|
||||||
|
#define EPSILON 0.000001f
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DEG2RAD
|
#ifndef DEG2RAD
|
||||||
#define DEG2RAD (PI/180.0f)
|
#define DEG2RAD (PI/180.0f)
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -194,6 +198,14 @@ RMAPI float Remap(float value, float inputStart, float inputEnd, float outputSta
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether two given floats are almost equal
|
||||||
|
RMAPI int FloatEquals(float x, float y)
|
||||||
|
{
|
||||||
|
int result = (fabsf(x - y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(x), fabsf(y))));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Vector2 math
|
// Module Functions Definition - Vector2 math
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -414,6 +426,62 @@ RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invert the given vector
|
||||||
|
RMAPI Vector2 Vector2Invert(Vector2 v)
|
||||||
|
{
|
||||||
|
Vector2 result = { 1.0f/v.x, 1.0f/v.y };
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp the components of the vector between
|
||||||
|
// min and max values specified by the given vectors
|
||||||
|
RMAPI Vector2 Vector2Clamp(Vector2 v, Vector2 min, Vector2 max)
|
||||||
|
{
|
||||||
|
Vector2 result = { 0 };
|
||||||
|
|
||||||
|
result.x = fminf(max.x, fmaxf(min.x, v.x));
|
||||||
|
result.y = fminf(max.y, fmaxf(min.y, v.y));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp the magnitude of the vector between two min and max values
|
||||||
|
RMAPI Vector2 Vector2ClampValue(Vector2 v, float min, float max)
|
||||||
|
{
|
||||||
|
Vector2 result = { 0 };
|
||||||
|
|
||||||
|
float length = (v.x*v.x) + (v.y*v.y);
|
||||||
|
if (length > 0.0f)
|
||||||
|
{
|
||||||
|
length = sqrtf(length);
|
||||||
|
|
||||||
|
if (length < min)
|
||||||
|
{
|
||||||
|
float scale = min/length;
|
||||||
|
result.x = v.x*scale;
|
||||||
|
result.y = v.y*scale;
|
||||||
|
}
|
||||||
|
else if (length > max)
|
||||||
|
{
|
||||||
|
float scale = max/length;
|
||||||
|
result.x = v.x*scale;
|
||||||
|
result.y = v.y*scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether two given vectors are almost equal
|
||||||
|
RMAPI int Vector2Equals(Vector2 p, Vector2 q)
|
||||||
|
{
|
||||||
|
int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
|
||||||
|
((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y)))));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Vector3 math
|
// Module Functions Definition - Vector3 math
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -498,14 +566,14 @@ RMAPI Vector3 Vector3Perpendicular(Vector3 v)
|
||||||
float min = (float) fabs(v.x);
|
float min = (float) fabs(v.x);
|
||||||
Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
|
Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
|
||||||
|
|
||||||
if (fabs(v.y) < min)
|
if (fabsf(v.y) < min)
|
||||||
{
|
{
|
||||||
min = (float) fabs(v.y);
|
min = (float) fabs(v.y);
|
||||||
Vector3 tmp = {0.0f, 1.0f, 0.0f};
|
Vector3 tmp = {0.0f, 1.0f, 0.0f};
|
||||||
cardinalAxis = tmp;
|
cardinalAxis = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabs(v.z) < min)
|
if (fabsf(v.z) < min)
|
||||||
{
|
{
|
||||||
Vector3 tmp = {0.0f, 0.0f, 1.0f};
|
Vector3 tmp = {0.0f, 0.0f, 1.0f};
|
||||||
cardinalAxis = tmp;
|
cardinalAxis = tmp;
|
||||||
|
|
@ -851,6 +919,92 @@ RMAPI float3 Vector3ToFloatV(Vector3 v)
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invert the given vector
|
||||||
|
RMAPI Vector3 Vector3Invert(Vector3 v)
|
||||||
|
{
|
||||||
|
Vector3 result = { 1.0f/v.x, 1.0f/v.y, 1.0f/v.z };
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp the components of the vector between
|
||||||
|
// min and max values specified by the given vectors
|
||||||
|
RMAPI Vector3 Vector3Clamp(Vector3 v, Vector3 min, Vector3 max)
|
||||||
|
{
|
||||||
|
Vector3 result = { 0 };
|
||||||
|
|
||||||
|
result.x = fminf(max.x, fmaxf(min.x, v.x));
|
||||||
|
result.y = fminf(max.y, fmaxf(min.y, v.y));
|
||||||
|
result.z = fminf(max.z, fmaxf(min.z, v.z));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clamp the magnitude of the vector between two values
|
||||||
|
RMAPI Vector3 Vector3ClampValue(Vector3 v, float min, float max)
|
||||||
|
{
|
||||||
|
Vector3 result = { 0 };
|
||||||
|
|
||||||
|
float length = (v.x*v.x) + (v.y*v.y) + (v.z*v.z);
|
||||||
|
if (length > 0.0f)
|
||||||
|
{
|
||||||
|
length = sqrtf(length);
|
||||||
|
|
||||||
|
if (length < min)
|
||||||
|
{
|
||||||
|
float scale = min/length;
|
||||||
|
result.x = v.x*scale;
|
||||||
|
result.y = v.y*scale;
|
||||||
|
result.z = v.z*scale;
|
||||||
|
}
|
||||||
|
else if (length > max)
|
||||||
|
{
|
||||||
|
float scale = max/length;
|
||||||
|
result.x = v.x*scale;
|
||||||
|
result.y = v.y*scale;
|
||||||
|
result.z = v.z*scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether two given vectors are almost equal
|
||||||
|
RMAPI int Vector3Equals(Vector3 p, Vector3 q)
|
||||||
|
{
|
||||||
|
int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
|
||||||
|
((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&
|
||||||
|
((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z)))));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the direction of a refracted ray where v specifies the
|
||||||
|
// normalized direction of the incoming ray, n specifies the
|
||||||
|
// normalized normal vector of the interface of two optical media,
|
||||||
|
// and r specifies the ratio of the refractive index of the medium
|
||||||
|
// from where the ray comes to the refractive index of the medium
|
||||||
|
// on the other side of the surface
|
||||||
|
RMAPI Vector3 Vector3Refract(Vector3 v, Vector3 n, float r)
|
||||||
|
{
|
||||||
|
Vector3 result = { 0 };
|
||||||
|
|
||||||
|
float dot = v.x*n.x + v.y*n.y + v.z*n.z;
|
||||||
|
float d = 1.0f - r*r*(1.0f - dot*dot);
|
||||||
|
|
||||||
|
if (d >= 0.0f)
|
||||||
|
{
|
||||||
|
d = sqrtf(d);
|
||||||
|
v.x = r*v.x - (r*dot + d)*n.x;
|
||||||
|
v.y = r*v.y - (r*dot + d)*n.y;
|
||||||
|
v.z = r*v.z - (r*dot + d)*n.z;
|
||||||
|
|
||||||
|
result = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Module Functions Definition - Matrix math
|
// Module Functions Definition - Matrix math
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
@ -956,45 +1110,6 @@ RMAPI Matrix MatrixInvert(Matrix mat)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize provided matrix
|
|
||||||
RMAPI Matrix MatrixNormalize(Matrix mat)
|
|
||||||
{
|
|
||||||
Matrix result = { 0 };
|
|
||||||
|
|
||||||
// Cache the matrix values (speed optimization)
|
|
||||||
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
|
||||||
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
|
||||||
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
|
||||||
float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
|
|
||||||
|
|
||||||
// MatrixDeterminant(mat)
|
|
||||||
float det = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
|
|
||||||
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
|
|
||||||
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
|
|
||||||
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
|
|
||||||
a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
|
|
||||||
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
|
|
||||||
|
|
||||||
result.m0 = mat.m0/det;
|
|
||||||
result.m1 = mat.m1/det;
|
|
||||||
result.m2 = mat.m2/det;
|
|
||||||
result.m3 = mat.m3/det;
|
|
||||||
result.m4 = mat.m4/det;
|
|
||||||
result.m5 = mat.m5/det;
|
|
||||||
result.m6 = mat.m6/det;
|
|
||||||
result.m7 = mat.m7/det;
|
|
||||||
result.m8 = mat.m8/det;
|
|
||||||
result.m9 = mat.m9/det;
|
|
||||||
result.m10 = mat.m10/det;
|
|
||||||
result.m11 = mat.m11/det;
|
|
||||||
result.m12 = mat.m12/det;
|
|
||||||
result.m13 = mat.m13/det;
|
|
||||||
result.m14 = mat.m14/det;
|
|
||||||
result.m15 = mat.m15/det;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get identity matrix
|
// Get identity matrix
|
||||||
RMAPI Matrix MatrixIdentity(void)
|
RMAPI Matrix MatrixIdentity(void)
|
||||||
{
|
{
|
||||||
|
|
@ -1516,7 +1631,7 @@ RMAPI Quaternion QuaternionInvert(Quaternion q)
|
||||||
|
|
||||||
float lengthSq = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w;
|
float lengthSq = q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w;
|
||||||
|
|
||||||
if (lengthSq != 0.0)
|
if (lengthSq != 0.0f)
|
||||||
{
|
{
|
||||||
float invLength = 1.0f/lengthSq;
|
float invLength = 1.0f/lengthSq;
|
||||||
|
|
||||||
|
|
@ -1550,12 +1665,10 @@ RMAPI Quaternion QuaternionScale(Quaternion q, float mul)
|
||||||
{
|
{
|
||||||
Quaternion result = { 0 };
|
Quaternion result = { 0 };
|
||||||
|
|
||||||
float qax = q.x, qay = q.y, qaz = q.z, qaw = q.w;
|
result.x = q.x*mul;
|
||||||
|
result.y = q.y*mul;
|
||||||
result.x = qax*mul + qaw*mul + qay*mul - qaz*mul;
|
result.z = q.z*mul;
|
||||||
result.y = qay*mul + qaw*mul + qaz*mul - qax*mul;
|
result.w = q.w*mul;
|
||||||
result.z = qaz*mul + qaw*mul + qax*mul - qay*mul;
|
|
||||||
result.w = qaw*mul - qax*mul - qay*mul - qaz*mul;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -1619,14 +1732,14 @@ RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
|
||||||
cosHalfTheta = -cosHalfTheta;
|
cosHalfTheta = -cosHalfTheta;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fabs(cosHalfTheta) >= 1.0f) result = q1;
|
if (fabsf(cosHalfTheta) >= 1.0f) result = q1;
|
||||||
else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount);
|
else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float halfTheta = acosf(cosHalfTheta);
|
float halfTheta = acosf(cosHalfTheta);
|
||||||
float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta);
|
float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta);
|
||||||
|
|
||||||
if (fabs(sinHalfTheta) < 0.001f)
|
if (fabsf(sinHalfTheta) < 0.001f)
|
||||||
{
|
{
|
||||||
result.x = (q1.x*0.5f + q2.x*0.5f);
|
result.x = (q1.x*0.5f + q2.x*0.5f);
|
||||||
result.y = (q1.y*0.5f + q2.y*0.5f);
|
result.y = (q1.y*0.5f + q2.y*0.5f);
|
||||||
|
|
@ -1792,7 +1905,7 @@ RMAPI Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
|
||||||
// Get the rotation angle and axis for a given quaternion
|
// Get the rotation angle and axis for a given quaternion
|
||||||
RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
|
RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
|
||||||
{
|
{
|
||||||
if (fabs(q.w) > 1.0f)
|
if (fabsf(q.w) > 1.0f)
|
||||||
{
|
{
|
||||||
// QuaternionNormalize(q);
|
// QuaternionNormalize(q);
|
||||||
float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
|
float length = sqrtf(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
|
||||||
|
|
@ -1885,4 +1998,15 @@ RMAPI Quaternion QuaternionTransform(Quaternion q, Matrix mat)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether two given quaternions are almost equal
|
||||||
|
RMAPI int QuaternionEquals(Quaternion p, Quaternion q)
|
||||||
|
{
|
||||||
|
int result = ((fabsf(p.x - q.x)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.x), fabsf(q.x))))) &&
|
||||||
|
((fabsf(p.y - q.y)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.y), fabsf(q.y))))) &&
|
||||||
|
((fabsf(p.z - q.z)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.z), fabsf(q.z))))) &&
|
||||||
|
((fabsf(p.w - q.w)) <= (EPSILON*fmaxf(1.0f, fmaxf(fabsf(p.w), fabsf(q.w)))));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // RAYMATH_H
|
#endif // RAYMATH_H
|
||||||
|
|
|
||||||
274
src/rcore.c
274
src/rcore.c
|
|
@ -184,7 +184,7 @@
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: srand(), rand(), atexit()
|
#include <stdlib.h> // Required for: srand(), rand(), atexit()
|
||||||
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
|
#include <stdio.h> // Required for: sprintf() [Used in OpenURL()]
|
||||||
#include <string.h> // Required for: strrchr(), strcmp(), strlen()
|
#include <string.h> // Required for: strrchr(), strcmp(), strlen(), memset()
|
||||||
#include <time.h> // Required for: time() [Used in InitTimer()]
|
#include <time.h> // Required for: time() [Used in InitTimer()]
|
||||||
#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
|
#include <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
|
||||||
|
|
||||||
|
|
@ -227,7 +227,7 @@
|
||||||
unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) || defined(__FreeBSD__)
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
|
#include <sys/time.h> // Required for: timespec, nanosleep(), select() - POSIX
|
||||||
|
|
||||||
//#define GLFW_EXPOSE_NATIVE_X11 // WARNING: Exposing Xlib.h > X.h results in dup symbols for Font type
|
//#define GLFW_EXPOSE_NATIVE_X11 // WARNING: Exposing Xlib.h > X.h results in dup symbols for Font type
|
||||||
|
|
@ -247,6 +247,7 @@
|
||||||
//#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...)
|
//#include <android/sensor.h> // Required for: Android sensors functions (accelerometer, gyroscope, light...)
|
||||||
#include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others
|
#include <android/window.h> // Required for: AWINDOW_FLAG_FULLSCREEN definition and others
|
||||||
#include <android_native_app_glue.h> // Required for: android_app struct and activity management
|
#include <android_native_app_glue.h> // Required for: android_app struct and activity management
|
||||||
|
#include <jni.h> // Required for: JNIEnv and JavaVM [Used in OpenURL()]
|
||||||
|
|
||||||
#include <EGL/egl.h> // Native platform windowing system interface
|
#include <EGL/egl.h> // Native platform windowing system interface
|
||||||
//#include <GLES2/gl2.h> // OpenGL ES 2.0 library (not required in this module, only in rlgl)
|
//#include <GLES2/gl2.h> // OpenGL ES 2.0 library (not required in this module, only in rlgl)
|
||||||
|
|
@ -411,6 +412,7 @@ typedef struct CoreData {
|
||||||
bool fullscreen; // Check if fullscreen mode is enabled
|
bool fullscreen; // Check if fullscreen mode is enabled
|
||||||
bool shouldClose; // Check if window set for closing
|
bool shouldClose; // Check if window set for closing
|
||||||
bool resizedLastFrame; // Check if window has been resized last frame
|
bool resizedLastFrame; // Check if window has been resized last frame
|
||||||
|
bool eventWaiting; // Wait for events before ending frame
|
||||||
|
|
||||||
Point position; // Window position on screen (required on fullscreen toggle)
|
Point position; // Window position on screen (required on fullscreen toggle)
|
||||||
Size display; // Display width and height (monitor, device-screen, LCD, ...)
|
Size display; // Display width and height (monitor, device-screen, LCD, ...)
|
||||||
|
|
@ -778,11 +780,15 @@ void InitWindow(int width, int height, const char *title)
|
||||||
|
|
||||||
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||||
|
|
||||||
// Initialize required global values different than 0
|
// Initialize global input state
|
||||||
|
memset(&CORE.Input, 0, sizeof(CORE.Input));
|
||||||
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
||||||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||||
CORE.Input.Gamepad.lastButtonPressed = -1;
|
CORE.Input.Gamepad.lastButtonPressed = -1;
|
||||||
|
#if defined(SUPPORT_EVENTS_WAITING)
|
||||||
|
CORE.Window.eventWaiting = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
CORE.Window.screen.width = width;
|
CORE.Window.screen.width = width;
|
||||||
|
|
@ -1211,39 +1217,39 @@ bool IsWindowState(unsigned int flag)
|
||||||
void ToggleFullscreen(void)
|
void ToggleFullscreen(void)
|
||||||
{
|
{
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
// NOTE: glfwSetWindowMonitor() doesn't work properly (bugs)
|
// TODO: glfwSetWindowMonitor() doesn't work properly (bugs)
|
||||||
if (!CORE.Window.fullscreen)
|
if (!CORE.Window.fullscreen)
|
||||||
{
|
{
|
||||||
// Store previous window position (in case we exit fullscreen)
|
// Store previous window position (in case we exit fullscreen)
|
||||||
glfwGetWindowPos(CORE.Window.handle, &CORE.Window.position.x, &CORE.Window.position.y);
|
glfwGetWindowPos(CORE.Window.handle, &CORE.Window.position.x, &CORE.Window.position.y);
|
||||||
|
|
||||||
int monitorCount = 0;
|
int monitorCount = 0;
|
||||||
|
int monitorIndex = GetCurrentMonitor();
|
||||||
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
|
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
|
||||||
|
|
||||||
int monitorIndex = GetCurrentMonitor();
|
|
||||||
|
|
||||||
// Use current monitor, so we correctly get the display the window is on
|
// Use current monitor, so we correctly get the display the window is on
|
||||||
GLFWmonitor* monitor = monitorIndex < monitorCount ? monitors[monitorIndex] : NULL;
|
GLFWmonitor *monitor = (monitorIndex < monitorCount)? monitors[monitorIndex] : NULL;
|
||||||
|
|
||||||
if (!monitor)
|
if (monitor == NULL)
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor");
|
TRACELOG(LOG_WARNING, "GLFW: Failed to get monitor");
|
||||||
|
|
||||||
CORE.Window.fullscreen = false; // Toggle fullscreen flag
|
CORE.Window.fullscreen = false;
|
||||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
glfwSetWindowMonitor(CORE.Window.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
glfwSetWindowMonitor(CORE.Window.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
CORE.Window.fullscreen = true; // Toggle fullscreen flag
|
{
|
||||||
|
CORE.Window.fullscreen = true;
|
||||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
glfwSetWindowMonitor(CORE.Window.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
glfwSetWindowMonitor(CORE.Window.handle, monitor, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CORE.Window.fullscreen = false; // Toggle fullscreen flag
|
CORE.Window.fullscreen = false;
|
||||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||||
|
|
||||||
glfwSetWindowMonitor(CORE.Window.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
glfwSetWindowMonitor(CORE.Window.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||||
|
|
@ -1934,6 +1940,29 @@ const char *GetMonitorName(int monitor)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set clipboard text content
|
||||||
|
void SetClipboardText(const char *text)
|
||||||
|
{
|
||||||
|
#if defined(PLATFORM_DESKTOP)
|
||||||
|
glfwSetClipboardString(CORE.Window.handle, text);
|
||||||
|
#endif
|
||||||
|
#if defined(PLATFORM_WEB)
|
||||||
|
emscripten_run_script(TextFormat("navigator.clipboard.writeText('%s')", text));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable waiting for events on EndDrawing(), no automatic event polling
|
||||||
|
void EnableEventWaiting(void)
|
||||||
|
{
|
||||||
|
CORE.Window.eventWaiting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable waiting for events on EndDrawing(), automatic events polling
|
||||||
|
RLAPI void DisableEventWaiting(void)
|
||||||
|
{
|
||||||
|
CORE.Window.eventWaiting = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Get clipboard text content
|
// Get clipboard text content
|
||||||
// NOTE: returned string is allocated and freed by GLFW
|
// NOTE: returned string is allocated and freed by GLFW
|
||||||
const char *GetClipboardText(void)
|
const char *GetClipboardText(void)
|
||||||
|
|
@ -1947,16 +1976,7 @@ const char *GetClipboardText(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set clipboard text content
|
|
||||||
void SetClipboardText(const char *text)
|
|
||||||
{
|
|
||||||
#if defined(PLATFORM_DESKTOP)
|
|
||||||
glfwSetClipboardString(CORE.Window.handle, text);
|
|
||||||
#endif
|
|
||||||
#if defined(PLATFORM_WEB)
|
|
||||||
emscripten_run_script(TextFormat("navigator.clipboard.writeText('%s')", text));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show mouse cursor
|
// Show mouse cursor
|
||||||
void ShowCursor(void)
|
void ShowCursor(void)
|
||||||
|
|
@ -2066,8 +2086,9 @@ void EndDrawing(void)
|
||||||
{
|
{
|
||||||
// Get image data for the current frame (from backbuffer)
|
// Get image data for the current frame (from backbuffer)
|
||||||
// NOTE: This process is quite slow... :(
|
// NOTE: This process is quite slow... :(
|
||||||
unsigned char *screenData = rlReadScreenPixels(CORE.Window.screen.width, CORE.Window.screen.height);
|
Vector2 scale = GetWindowScaleDPI();
|
||||||
msf_gif_frame(&gifState, screenData, 10, 16, CORE.Window.screen.width*4);
|
unsigned char *screenData = rlReadScreenPixels(CORE.Window.render.width*scale.x, CORE.Window.render.height*scale.y);
|
||||||
|
msf_gif_frame(&gifState, screenData, 10, 16, CORE.Window.render.width*scale.x*4);
|
||||||
|
|
||||||
RL_FREE(screenData); // Free image data
|
RL_FREE(screenData); // Free image data
|
||||||
}
|
}
|
||||||
|
|
@ -2236,8 +2257,10 @@ void BeginTextureMode(RenderTexture2D target)
|
||||||
|
|
||||||
rlEnableFramebuffer(target.id); // Enable render target
|
rlEnableFramebuffer(target.id); // Enable render target
|
||||||
|
|
||||||
// Set viewport to framebuffer size
|
// Set viewport and RLGL internal framebuffer size
|
||||||
rlViewport(0, 0, target.texture.width, target.texture.height);
|
rlViewport(0, 0, target.texture.width, target.texture.height);
|
||||||
|
rlSetFramebufferWidth(target.texture.width);
|
||||||
|
rlSetFramebufferHeight(target.texture.height);
|
||||||
|
|
||||||
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||||
rlLoadIdentity(); // Reset current matrix (projection)
|
rlLoadIdentity(); // Reset current matrix (projection)
|
||||||
|
|
@ -2383,8 +2406,8 @@ VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device)
|
||||||
|
|
||||||
// Fovy is normally computed with: 2*atan2f(device.vScreenSize, 2*device.eyeToScreenDistance)
|
// Fovy is normally computed with: 2*atan2f(device.vScreenSize, 2*device.eyeToScreenDistance)
|
||||||
// ...but with lens distortion it is increased (see Oculus SDK Documentation)
|
// ...but with lens distortion it is increased (see Oculus SDK Documentation)
|
||||||
//float fovy = 2.0f*atan2f(device.vScreenSize*0.5f*distortionScale, device.eyeToScreenDistance); // Really need distortionScale?
|
float fovy = 2.0f*atan2f(device.vScreenSize*0.5f*distortionScale, device.eyeToScreenDistance); // Really need distortionScale?
|
||||||
float fovy = 2.0f*(float)atan2f(device.vScreenSize*0.5f, device.eyeToScreenDistance);
|
// float fovy = 2.0f*(float)atan2f(device.vScreenSize*0.5f, device.eyeToScreenDistance);
|
||||||
|
|
||||||
// Compute camera projection matrices
|
// Compute camera projection matrices
|
||||||
float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1]
|
float projOffset = 4.0f*lensShift; // Scaled to projection space coordinates [-1..1]
|
||||||
|
|
@ -2710,7 +2733,7 @@ void SetTargetFPS(int fps)
|
||||||
if (fps < 1) CORE.Time.target = 0.0;
|
if (fps < 1) CORE.Time.target = 0.0;
|
||||||
else CORE.Time.target = 1.0/(double)fps;
|
else CORE.Time.target = 1.0/(double)fps;
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "TIMER: Target time per frame: %02.03f milliseconds", (float)CORE.Time.target*1000);
|
TRACELOG(LOG_INFO, "TIMER: Target time per frame: %02.03f milliseconds", (float)CORE.Time.target*1000.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current FPS
|
// Get current FPS
|
||||||
|
|
@ -2787,8 +2810,9 @@ void SetConfigFlags(unsigned int flags)
|
||||||
void TakeScreenshot(const char *fileName)
|
void TakeScreenshot(const char *fileName)
|
||||||
{
|
{
|
||||||
#if defined(SUPPORT_MODULE_RTEXTURES)
|
#if defined(SUPPORT_MODULE_RTEXTURES)
|
||||||
unsigned char *imgData = rlReadScreenPixels(CORE.Window.render.width, CORE.Window.render.height);
|
Vector2 scale = GetWindowScaleDPI();
|
||||||
Image image = { imgData, CORE.Window.render.width, CORE.Window.render.height, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
unsigned char *imgData = rlReadScreenPixels(CORE.Window.render.width*scale.x, CORE.Window.render.height*scale.y);
|
||||||
|
Image image = { imgData, CORE.Window.render.width*scale.x, CORE.Window.render.height*scale.y, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
||||||
|
|
||||||
char path[2048] = { 0 };
|
char path[2048] = { 0 };
|
||||||
strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName));
|
strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName));
|
||||||
|
|
@ -2943,7 +2967,7 @@ const char *GetFileName(const char *filePath)
|
||||||
// Get filename string without extension (uses static string)
|
// Get filename string without extension (uses static string)
|
||||||
const char *GetFileNameWithoutExt(const char *filePath)
|
const char *GetFileNameWithoutExt(const char *filePath)
|
||||||
{
|
{
|
||||||
#define MAX_FILENAMEWITHOUTEXT_LENGTH 128
|
#define MAX_FILENAMEWITHOUTEXT_LENGTH 256
|
||||||
|
|
||||||
static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH] = { 0 };
|
static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH] = { 0 };
|
||||||
memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH);
|
memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH);
|
||||||
|
|
@ -3222,8 +3246,8 @@ long GetFileModTime(const char *fileName)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compress data (DEFLATE algorythm)
|
// Compress data (DEFLATE algorithm)
|
||||||
unsigned char *CompressData(const unsigned char *data, int dataLength, int *compDataLength)
|
unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize)
|
||||||
{
|
{
|
||||||
#define COMPRESSION_QUALITY_DEFLATE 8
|
#define COMPRESSION_QUALITY_DEFLATE 8
|
||||||
|
|
||||||
|
|
@ -3232,40 +3256,40 @@ unsigned char *CompressData(const unsigned char *data, int dataLength, int *comp
|
||||||
#if defined(SUPPORT_COMPRESSION_API)
|
#if defined(SUPPORT_COMPRESSION_API)
|
||||||
// Compress data and generate a valid DEFLATE stream
|
// Compress data and generate a valid DEFLATE stream
|
||||||
struct sdefl sdefl = { 0 };
|
struct sdefl sdefl = { 0 };
|
||||||
int bounds = sdefl_bound(dataLength);
|
int bounds = sdefl_bound(dataSize);
|
||||||
compData = (unsigned char *)RL_CALLOC(bounds, 1);
|
compData = (unsigned char *)RL_CALLOC(bounds, 1);
|
||||||
*compDataLength = sdeflate(&sdefl, compData, data, dataLength, COMPRESSION_QUALITY_DEFLATE); // Compression level 8, same as stbwi
|
*compDataSize = sdeflate(&sdefl, compData, data, dataSize, COMPRESSION_QUALITY_DEFLATE); // Compression level 8, same as stbwi
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "SYSTEM: Compress data: Original size: %i -> Comp. size: %i", dataLength, *compDataLength);
|
TraceLog(LOG_INFO, "SYSTEM: Compress data: Original size: %i -> Comp. size: %i", dataSize, *compDataSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return compData;
|
return compData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decompress data (DEFLATE algorythm)
|
// Decompress data (DEFLATE algorithm)
|
||||||
unsigned char *DecompressData(const unsigned char *compData, int compDataLength, int *dataLength)
|
unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize)
|
||||||
{
|
{
|
||||||
unsigned char *data = NULL;
|
unsigned char *data = NULL;
|
||||||
|
|
||||||
#if defined(SUPPORT_COMPRESSION_API)
|
#if defined(SUPPORT_COMPRESSION_API)
|
||||||
// Decompress data from a valid DEFLATE stream
|
// Decompress data from a valid DEFLATE stream
|
||||||
data = RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1);
|
data = RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1);
|
||||||
int length = sinflate(data, MAX_DECOMPRESSION_SIZE, compData, compDataLength);
|
int length = sinflate(data, MAX_DECOMPRESSION_SIZE, compData, compDataSize);
|
||||||
unsigned char *temp = RL_REALLOC(data, length);
|
unsigned char *temp = RL_REALLOC(data, length);
|
||||||
|
|
||||||
if (temp != NULL) data = temp;
|
if (temp != NULL) data = temp;
|
||||||
else TRACELOG(LOG_WARNING, "SYSTEM: Failed to re-allocate required decompression memory");
|
else TRACELOG(LOG_WARNING, "SYSTEM: Failed to re-allocate required decompression memory");
|
||||||
|
|
||||||
*dataLength = length;
|
*dataSize = length;
|
||||||
|
|
||||||
TraceLog(LOG_INFO, "SYSTEM: Decompress data: Comp. size: %i -> Original size: %i", compDataLength, *dataLength);
|
TraceLog(LOG_INFO, "SYSTEM: Decompress data: Comp. size: %i -> Original size: %i", compDataSize, *dataSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode data to Base64 string
|
// Encode data to Base64 string
|
||||||
char *EncodeDataBase64(const unsigned char *data, int dataLength, int *outputLength)
|
char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize)
|
||||||
{
|
{
|
||||||
static const unsigned char base64encodeTable[] = {
|
static const unsigned char base64encodeTable[] = {
|
||||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||||
|
|
@ -3275,17 +3299,17 @@ char *EncodeDataBase64(const unsigned char *data, int dataLength, int *outputLen
|
||||||
|
|
||||||
static const int modTable[] = { 0, 2, 1 };
|
static const int modTable[] = { 0, 2, 1 };
|
||||||
|
|
||||||
*outputLength = 4*((dataLength + 2)/3);
|
*outputSize = 4*((dataSize + 2)/3);
|
||||||
|
|
||||||
char *encodedData = RL_MALLOC(*outputLength);
|
char *encodedData = RL_MALLOC(*outputSize);
|
||||||
|
|
||||||
if (encodedData == NULL) return NULL;
|
if (encodedData == NULL) return NULL;
|
||||||
|
|
||||||
for (int i = 0, j = 0; i < dataLength;)
|
for (int i = 0, j = 0; i < dataSize;)
|
||||||
{
|
{
|
||||||
unsigned int octetA = (i < dataLength)? (unsigned char)data[i++] : 0;
|
unsigned int octetA = (i < dataSize)? (unsigned char)data[i++] : 0;
|
||||||
unsigned int octetB = (i < dataLength)? (unsigned char)data[i++] : 0;
|
unsigned int octetB = (i < dataSize)? (unsigned char)data[i++] : 0;
|
||||||
unsigned int octetC = (i < dataLength)? (unsigned char)data[i++] : 0;
|
unsigned int octetC = (i < dataSize)? (unsigned char)data[i++] : 0;
|
||||||
|
|
||||||
unsigned int triple = (octetA << 0x10) + (octetB << 0x08) + octetC;
|
unsigned int triple = (octetA << 0x10) + (octetB << 0x08) + octetC;
|
||||||
|
|
||||||
|
|
@ -3295,13 +3319,13 @@ char *EncodeDataBase64(const unsigned char *data, int dataLength, int *outputLen
|
||||||
encodedData[j++] = base64encodeTable[(triple >> 0*6) & 0x3F];
|
encodedData[j++] = base64encodeTable[(triple >> 0*6) & 0x3F];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < modTable[dataLength%3]; i++) encodedData[*outputLength - 1 - i] = '='; // Padding character
|
for (int i = 0; i < modTable[dataSize%3]; i++) encodedData[*outputSize - 1 - i] = '='; // Padding character
|
||||||
|
|
||||||
return encodedData;
|
return encodedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode Base64 string data
|
// Decode Base64 string data
|
||||||
unsigned char *DecodeDataBase64(const unsigned char *data, int *outputLength)
|
unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize)
|
||||||
{
|
{
|
||||||
static const unsigned char base64decodeTable[] = {
|
static const unsigned char base64decodeTable[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
@ -3311,21 +3335,21 @@ unsigned char *DecodeDataBase64(const unsigned char *data, int *outputLength)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get output size of Base64 input data
|
// Get output size of Base64 input data
|
||||||
int outLength = 0;
|
int outSize = 0;
|
||||||
for (int i = 0; data[4*i] != 0; i++)
|
for (int i = 0; data[4*i] != 0; i++)
|
||||||
{
|
{
|
||||||
if (data[4*i + 3] == '=')
|
if (data[4*i + 3] == '=')
|
||||||
{
|
{
|
||||||
if (data[4*i + 2] == '=') outLength += 1;
|
if (data[4*i + 2] == '=') outSize += 1;
|
||||||
else outLength += 2;
|
else outSize += 2;
|
||||||
}
|
}
|
||||||
else outLength += 3;
|
else outSize += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate memory to store decoded Base64 data
|
// Allocate memory to store decoded Base64 data
|
||||||
unsigned char *decodedData = (unsigned char *)RL_MALLOC(outLength);
|
unsigned char *decodedData = (unsigned char *)RL_MALLOC(outSize);
|
||||||
|
|
||||||
for (int i = 0; i < outLength/3; i++)
|
for (int i = 0; i < outSize/3; i++)
|
||||||
{
|
{
|
||||||
unsigned char a = base64decodeTable[(int)data[4*i]];
|
unsigned char a = base64decodeTable[(int)data[4*i]];
|
||||||
unsigned char b = base64decodeTable[(int)data[4*i + 1]];
|
unsigned char b = base64decodeTable[(int)data[4*i + 1]];
|
||||||
|
|
@ -3337,24 +3361,24 @@ unsigned char *DecodeDataBase64(const unsigned char *data, int *outputLength)
|
||||||
decodedData[3*i + 2] = (c << 6) | d;
|
decodedData[3*i + 2] = (c << 6) | d;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outLength%3 == 1)
|
if (outSize%3 == 1)
|
||||||
{
|
{
|
||||||
int n = outLength/3;
|
int n = outSize/3;
|
||||||
unsigned char a = base64decodeTable[(int)data[4*n]];
|
unsigned char a = base64decodeTable[(int)data[4*n]];
|
||||||
unsigned char b = base64decodeTable[(int)data[4*n + 1]];
|
unsigned char b = base64decodeTable[(int)data[4*n + 1]];
|
||||||
decodedData[outLength - 1] = (a << 2) | (b >> 4);
|
decodedData[outSize - 1] = (a << 2) | (b >> 4);
|
||||||
}
|
}
|
||||||
else if (outLength%3 == 2)
|
else if (outSize%3 == 2)
|
||||||
{
|
{
|
||||||
int n = outLength/3;
|
int n = outSize/3;
|
||||||
unsigned char a = base64decodeTable[(int)data[4*n]];
|
unsigned char a = base64decodeTable[(int)data[4*n]];
|
||||||
unsigned char b = base64decodeTable[(int)data[4*n + 1]];
|
unsigned char b = base64decodeTable[(int)data[4*n + 1]];
|
||||||
unsigned char c = base64decodeTable[(int)data[4*n + 2]];
|
unsigned char c = base64decodeTable[(int)data[4*n + 2]];
|
||||||
decodedData[outLength - 2] = (a << 2) | (b >> 4);
|
decodedData[outSize - 2] = (a << 2) | (b >> 4);
|
||||||
decodedData[outLength - 1] = (b << 4) | (c >> 2);
|
decodedData[outSize - 1] = (b << 4) | (c >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
*outputLength = outLength;
|
*outputSize = outSize;
|
||||||
return decodedData;
|
return decodedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3480,9 +3504,9 @@ void OpenURL(const char *url)
|
||||||
#if defined(PLATFORM_DESKTOP)
|
#if defined(PLATFORM_DESKTOP)
|
||||||
char *cmd = (char *)RL_CALLOC(strlen(url) + 10, sizeof(char));
|
char *cmd = (char *)RL_CALLOC(strlen(url) + 10, sizeof(char));
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
sprintf(cmd, "explorer %s", url);
|
sprintf(cmd, "explorer \"%s\"", url);
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) || defined(__FreeBSD__)
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
sprintf(cmd, "xdg-open '%s'", url); // Alternatives: firefox, x-www-browser
|
sprintf(cmd, "xdg-open '%s'", url); // Alternatives: firefox, x-www-browser
|
||||||
#endif
|
#endif
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
|
@ -3494,6 +3518,29 @@ void OpenURL(const char *url)
|
||||||
#endif
|
#endif
|
||||||
#if defined(PLATFORM_WEB)
|
#if defined(PLATFORM_WEB)
|
||||||
emscripten_run_script(TextFormat("window.open('%s', '_blank')", url));
|
emscripten_run_script(TextFormat("window.open('%s', '_blank')", url));
|
||||||
|
#endif
|
||||||
|
#if defined(PLATFORM_ANDROID)
|
||||||
|
JNIEnv *env = NULL;
|
||||||
|
JavaVM *vm = CORE.Android.app->activity->vm;
|
||||||
|
(*vm)->AttachCurrentThread(vm, &env, NULL);
|
||||||
|
|
||||||
|
jstring urlString = (*env)->NewStringUTF(env, url);
|
||||||
|
jclass uriClass = (*env)->FindClass(env, "android/net/Uri");
|
||||||
|
jmethodID uriParse = (*env)->GetStaticMethodID(env, uriClass, "parse", "(Ljava/lang/String;)Landroid/net/Uri;");
|
||||||
|
jobject uri = (*env)->CallStaticObjectMethod(env, uriClass, uriParse, urlString);
|
||||||
|
|
||||||
|
jclass intentClass = (*env)->FindClass(env, "android/content/Intent");
|
||||||
|
jfieldID actionViewId = (*env)->GetStaticFieldID(env, intentClass, "ACTION_VIEW", "Ljava/lang/String;");
|
||||||
|
jobject actionView = (*env)->GetStaticObjectField(env, intentClass, actionViewId);
|
||||||
|
jmethodID newIntent = (*env)->GetMethodID(env, intentClass, "<init>", "(Ljava/lang/String;Landroid/net/Uri;)V");
|
||||||
|
jobject intent = (*env)->AllocObject(env, intentClass);
|
||||||
|
|
||||||
|
(*env)->CallVoidMethod(env, intent, newIntent, actionView, uri);
|
||||||
|
jclass activityClass = (*env)->FindClass(env, "android/app/Activity");
|
||||||
|
jmethodID startActivity = (*env)->GetMethodID(env, activityClass, "startActivity", "(Landroid/content/Intent;)V");
|
||||||
|
(*env)->CallVoidMethod(env, CORE.Android.app->activity->clazz, startActivity, intent);
|
||||||
|
|
||||||
|
(*vm)->DetachCurrentThread(vm);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4848,7 +4895,7 @@ void WaitTime(float ms)
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
Sleep((unsigned int)ms);
|
Sleep((unsigned int)ms);
|
||||||
#endif
|
#endif
|
||||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__)
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
|
||||||
struct timespec req = { 0 };
|
struct timespec req = { 0 };
|
||||||
time_t sec = (int)(ms/1000.0f);
|
time_t sec = (int)(ms/1000.0f);
|
||||||
ms -= (sec*1000);
|
ms -= (sec*1000);
|
||||||
|
|
@ -4867,7 +4914,7 @@ void WaitTime(float ms)
|
||||||
double currentTime = 0.0;
|
double currentTime = 0.0;
|
||||||
|
|
||||||
// Partial busy wait loop (only a fraction of the total wait time)
|
// Partial busy wait loop (only a fraction of the total wait time)
|
||||||
while ((currentTime - previousTime) < busyWait/1000.0f) currentTime = GetTime();
|
while ((currentTime - previousTime) < (busyWait/1000.0f)) currentTime = GetTime();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
@ -4883,53 +4930,31 @@ void SwapScreenBuffer(void)
|
||||||
eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
||||||
|
|
||||||
#if defined(PLATFORM_DRM)
|
#if defined(PLATFORM_DRM)
|
||||||
if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc)
|
|
||||||
{
|
if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface);
|
struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface);
|
||||||
if (!bo)
|
if (!bo) TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t fb = 0;
|
uint32_t fb = 0;
|
||||||
int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay,
|
int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay, CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
||||||
CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
||||||
if (0 != result)
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0,
|
result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0, &CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]);
|
||||||
&CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]);
|
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
||||||
if (0 != result)
|
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CORE.Window.prevFB)
|
if (CORE.Window.prevFB)
|
||||||
{
|
{
|
||||||
result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
||||||
if (0 != result)
|
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
||||||
{
|
|
||||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CORE.Window.prevFB = fb;
|
CORE.Window.prevFB = fb;
|
||||||
|
|
||||||
if (CORE.Window.prevBO)
|
if (CORE.Window.prevBO) gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
||||||
{
|
|
||||||
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
|
||||||
}
|
|
||||||
|
|
||||||
CORE.Window.prevBO = bo;
|
CORE.Window.prevBO = bo;
|
||||||
|
|
||||||
#endif // PLATFORM_DRM
|
#endif // PLATFORM_DRM
|
||||||
#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_NX
|
#endif // PLATFORM_ANDROID || PLATFORM_RPI || PLATFORM_DRM || PLATFORM_NX
|
||||||
}
|
}
|
||||||
|
|
@ -5077,8 +5102,8 @@ void PollInputEvents(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register buttons for 2nd triggers (because GLFW doesn't count these as buttons but rather axis)
|
// Register buttons for 2nd triggers (because GLFW doesn't count these as buttons but rather axis)
|
||||||
CORE.Input.Gamepad.currentButtonState[i][GAMEPAD_BUTTON_LEFT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] > 0.1);
|
CORE.Input.Gamepad.currentButtonState[i][GAMEPAD_BUTTON_LEFT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] > 0.1f);
|
||||||
CORE.Input.Gamepad.currentButtonState[i][GAMEPAD_BUTTON_RIGHT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] > 0.1);
|
CORE.Input.Gamepad.currentButtonState[i][GAMEPAD_BUTTON_RIGHT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] > 0.1f);
|
||||||
|
|
||||||
CORE.Input.Gamepad.axisCount = GLFW_GAMEPAD_AXIS_LAST + 1;
|
CORE.Input.Gamepad.axisCount = GLFW_GAMEPAD_AXIS_LAST + 1;
|
||||||
}
|
}
|
||||||
|
|
@ -5086,11 +5111,8 @@ void PollInputEvents(void)
|
||||||
|
|
||||||
CORE.Window.resizedLastFrame = false;
|
CORE.Window.resizedLastFrame = false;
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_WAITING)
|
if (CORE.Window.eventWaiting) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused)
|
||||||
glfwWaitEvents();
|
else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks)
|
||||||
#else
|
|
||||||
glfwPollEvents(); // Register keyboard/mouse events (callbacks)... and window events!
|
|
||||||
#endif
|
|
||||||
#endif // PLATFORM_DESKTOP
|
#endif // PLATFORM_DESKTOP
|
||||||
|
|
||||||
#if defined(PLATFORM_WEB)
|
#if defined(PLATFORM_WEB)
|
||||||
|
|
@ -5514,7 +5536,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
||||||
gifRecording = true;
|
gifRecording = true;
|
||||||
gifFrameCounter = 0;
|
gifFrameCounter = 0;
|
||||||
|
|
||||||
msf_gif_begin(&gifState, CORE.Window.screen.width, CORE.Window.screen.height);
|
Vector2 scale = GetWindowScaleDPI();
|
||||||
|
msf_gif_begin(&gifState, CORE.Window.render.width*scale.x, CORE.Window.render.height*scale.y);
|
||||||
screenshotCounter++;
|
screenshotCounter++;
|
||||||
|
|
||||||
TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter));
|
TRACELOG(LOG_INFO, "SYSTEM: Start animated GIF recording: %s", TextFormat("screenrec%03i.gif", screenshotCounter));
|
||||||
|
|
@ -5632,10 +5655,10 @@ static void MouseCursorPosCallback(GLFWwindow *window, double x, double y)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// GLFW3 Srolling Callback, runs on mouse wheel
|
// GLFW3 Scrolling Callback, runs on mouse wheel
|
||||||
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
|
static void MouseScrollCallback(GLFWwindow *window, double xoffset, double yoffset)
|
||||||
{
|
{
|
||||||
if (xoffset != 0.0) CORE.Input.Mouse.currentWheelMove = (float)xoffset;
|
if (fabs(xoffset) > fabs(yoffset)) CORE.Input.Mouse.currentWheelMove = (float)xoffset;
|
||||||
else CORE.Input.Mouse.currentWheelMove = (float)yoffset;
|
else CORE.Input.Mouse.currentWheelMove = (float)yoffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6227,7 +6250,8 @@ static void InitEvdevInput(void)
|
||||||
{
|
{
|
||||||
while ((entity = readdir(directory)) != NULL)
|
while ((entity = readdir(directory)) != NULL)
|
||||||
{
|
{
|
||||||
if (strncmp("event", entity->d_name, strlen("event")) == 0) // Search for devices named "event*"
|
if ((strncmp("event", entity->d_name, strlen("event")) == 0) || // Search for devices named "event*"
|
||||||
|
(strncmp("mouse", entity->d_name, strlen("mouse")) == 0)) // Search for devices named "mouse*"
|
||||||
{
|
{
|
||||||
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
|
sprintf(path, "%s%s", DEFAULT_EVDEV_PATH, entity->d_name);
|
||||||
ConfigureEvdevDevice(path); // Configure the device if appropriate
|
ConfigureEvdevDevice(path); // Configure the device if appropriate
|
||||||
|
|
@ -6387,7 +6411,7 @@ static void ConfigureEvdevDevice(char *device)
|
||||||
|
|
||||||
// Decide what to do with the device
|
// Decide what to do with the device
|
||||||
//-------------------------------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------------------------------
|
||||||
if (worker->isKeyboard && CORE.Input.Keyboard.fd == -1)
|
if (worker->isKeyboard && (CORE.Input.Keyboard.fd == -1))
|
||||||
{
|
{
|
||||||
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
|
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
|
||||||
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
|
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
|
||||||
|
|
@ -6838,7 +6862,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh,
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh,
|
||||||
(mode->flags & DRM_MODE_FLAG_INTERLACE) ? "interlaced" : "progressive");
|
(mode->flags & DRM_MODE_FLAG_INTERLACE) ? "interlaced" : "progressive");
|
||||||
|
|
||||||
if ((mode->hdisplay < width) || (mode->vdisplay < height) || (mode->vrefresh < fps))
|
if ((mode->hdisplay < width) || (mode->vdisplay < height))
|
||||||
{
|
{
|
||||||
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode is too small");
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode is too small");
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -6850,23 +6874,22 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mode->hdisplay >= width) && (mode->vdisplay >= height) && (mode->vrefresh >= fps))
|
|
||||||
{
|
|
||||||
const int widthDiff = mode->hdisplay - width;
|
|
||||||
const int heightDiff = mode->vdisplay - height;
|
|
||||||
const int fpsDiff = mode->vrefresh - fps;
|
|
||||||
|
|
||||||
if (nearestIndex < 0)
|
if (nearestIndex < 0)
|
||||||
{
|
{
|
||||||
nearestIndex = i;
|
nearestIndex = i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int nearestWidthDiff = CORE.Window.connector->modes[nearestIndex].hdisplay - width;
|
const int widthDiff = abs(mode->hdisplay - width);
|
||||||
const int nearestHeightDiff = CORE.Window.connector->modes[nearestIndex].vdisplay - height;
|
const int heightDiff = abs(mode->vdisplay - height);
|
||||||
const int nearestFpsDiff = CORE.Window.connector->modes[nearestIndex].vrefresh - fps;
|
const int fpsDiff = abs(mode->vrefresh - fps);
|
||||||
|
|
||||||
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) nearestIndex = i;
|
const int nearestWidthDiff = abs(CORE.Window.connector->modes[nearestIndex].hdisplay - width);
|
||||||
|
const int nearestHeightDiff = abs(CORE.Window.connector->modes[nearestIndex].vdisplay - height);
|
||||||
|
const int nearestFpsDiff = abs(CORE.Window.connector->modes[nearestIndex].vrefresh - fps);
|
||||||
|
|
||||||
|
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) {
|
||||||
|
nearestIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6876,6 +6899,7 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
||||||
|
|
||||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||||
// NOTE: Loading happens over AutomationEvent *events
|
// NOTE: Loading happens over AutomationEvent *events
|
||||||
|
// TODO: This system should probably be redesigned
|
||||||
static void LoadAutomationEvents(const char *fileName)
|
static void LoadAutomationEvents(const char *fileName)
|
||||||
{
|
{
|
||||||
//unsigned char fileId[4] = { 0 };
|
//unsigned char fileId[4] = { 0 };
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,10 @@
|
||||||
// NOTE: Below types are required for GESTURES_STANDALONE usage
|
// NOTE: Below types are required for GESTURES_STANDALONE usage
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Boolean type
|
// Boolean type
|
||||||
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
|
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
||||||
typedef enum bool { false, true } bool;
|
typedef enum bool { false = 0, true = !false } bool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(RL_VECTOR2_TYPE)
|
#if !defined(RL_VECTOR2_TYPE)
|
||||||
|
|
|
||||||
34
src/rlgl.h
34
src/rlgl.h
|
|
@ -358,11 +358,11 @@ typedef struct rlRenderBatch {
|
||||||
float currentDepth; // Current depth value for next draw
|
float currentDepth; // Current depth value for next draw
|
||||||
} rlRenderBatch;
|
} rlRenderBatch;
|
||||||
|
|
||||||
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
|
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
||||||
// Boolean type
|
// Boolean type
|
||||||
typedef enum bool { false, true } bool;
|
typedef enum bool { false = 0, true = !false } bool;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(RL_MATRIX_TYPE)
|
#if !defined(RL_MATRIX_TYPE)
|
||||||
|
|
@ -598,7 +598,9 @@ RLAPI void rlglInit(int width, int height); // Initialize rlgl (buffer
|
||||||
RLAPI void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures)
|
RLAPI void rlglClose(void); // De-inititialize rlgl (buffers, shaders, textures)
|
||||||
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
|
RLAPI void rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
|
||||||
RLAPI int rlGetVersion(void); // Get current OpenGL version
|
RLAPI int rlGetVersion(void); // Get current OpenGL version
|
||||||
|
RLAPI void rlSetFramebufferWidth(int width); // Set current framebuffer width
|
||||||
RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
|
RLAPI int rlGetFramebufferWidth(void); // Get default framebuffer width
|
||||||
|
RLAPI void rlSetFramebufferHeight(int height); // Set current framebuffer height
|
||||||
RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height
|
RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height
|
||||||
|
|
||||||
RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id
|
RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id
|
||||||
|
|
@ -927,8 +929,8 @@ typedef struct rlglData {
|
||||||
int glBlendDstFactor; // Blending destination factor
|
int glBlendDstFactor; // Blending destination factor
|
||||||
int glBlendEquation; // Blending equation
|
int glBlendEquation; // Blending equation
|
||||||
|
|
||||||
int framebufferWidth; // Default framebuffer width
|
int framebufferWidth; // Current framebuffer width
|
||||||
int framebufferHeight; // Default framebuffer height
|
int framebufferHeight; // Current framebuffer height
|
||||||
|
|
||||||
} State; // Renderer state
|
} State; // Renderer state
|
||||||
struct {
|
struct {
|
||||||
|
|
@ -1230,6 +1232,7 @@ void rlOrtho(double left, double right, double bottom, double top, double znear,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set the viewport area (transformation from normalized device coordinates to window coordinates)
|
// Set the viewport area (transformation from normalized device coordinates to window coordinates)
|
||||||
|
// NOTE: We store current viewport dimensions
|
||||||
void rlViewport(int x, int y, int width, int height)
|
void rlViewport(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
glViewport(x, y, width, height);
|
glViewport(x, y, width, height);
|
||||||
|
|
@ -1537,7 +1540,7 @@ void rlTextureParameters(unsigned int id, int param, int value)
|
||||||
if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
|
if (value <= RLGL.ExtSupported.maxAnisotropyLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
|
||||||
else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f)
|
else if (RLGL.ExtSupported.maxAnisotropyLevel > 0.0f)
|
||||||
{
|
{
|
||||||
TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, RLGL.ExtSupported.maxAnisotropyLevel);
|
TRACELOG(RL_LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, (int)RLGL.ExtSupported.maxAnisotropyLevel);
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
|
||||||
}
|
}
|
||||||
else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported");
|
else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported");
|
||||||
|
|
@ -2219,6 +2222,22 @@ int rlGetVersion(void)
|
||||||
return glVersion;
|
return glVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set current framebuffer width
|
||||||
|
void rlSetFramebufferWidth(int width)
|
||||||
|
{
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
RLGL.State.framebufferWidth = width;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set current framebuffer height
|
||||||
|
void rlSetFramebufferHeight(int height)
|
||||||
|
{
|
||||||
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
|
RLGL.State.framebufferHeight = height;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Get default framebuffer width
|
// Get default framebuffer width
|
||||||
int rlGetFramebufferWidth(void)
|
int rlGetFramebufferWidth(void)
|
||||||
{
|
{
|
||||||
|
|
@ -2601,6 +2620,9 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
|
||||||
|
|
||||||
glUseProgram(0); // Unbind shader program
|
glUseProgram(0); // Unbind shader program
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore viewport to default measures
|
||||||
|
if (eyeCount == 2) rlViewport(0, 0, RLGL.State.framebufferWidth, RLGL.State.framebufferHeight);
|
||||||
//------------------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Reset batch buffers
|
// Reset batch buffers
|
||||||
|
|
@ -3088,7 +3110,7 @@ void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int
|
||||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||||
if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
|
if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
|
||||||
{
|
{
|
||||||
//glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorythm: GL_FASTEST, GL_NICEST, GL_DONT_CARE
|
//glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE); // Hint for mipmaps generation algorithm: GL_FASTEST, GL_NICEST, GL_DONT_CARE
|
||||||
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
|
glGenerateMipmap(GL_TEXTURE_2D); // Generate mipmaps automatically
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
|
||||||
|
|
@ -3284,10 +3284,10 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota
|
||||||
Color color = model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color;
|
Color color = model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color;
|
||||||
|
|
||||||
Color colorTint = WHITE;
|
Color colorTint = WHITE;
|
||||||
colorTint.r = (unsigned char)((((float)color.r/255.0)*((float)tint.r/255.0))*255.0f);
|
colorTint.r = (unsigned char)((((float)color.r/255.0f)*((float)tint.r/255.0f))*255.0f);
|
||||||
colorTint.g = (unsigned char)((((float)color.g/255.0)*((float)tint.g/255.0))*255.0f);
|
colorTint.g = (unsigned char)((((float)color.g/255.0f)*((float)tint.g/255.0f))*255.0f);
|
||||||
colorTint.b = (unsigned char)((((float)color.b/255.0)*((float)tint.b/255.0))*255.0f);
|
colorTint.b = (unsigned char)((((float)color.b/255.0f)*((float)tint.b/255.0f))*255.0f);
|
||||||
colorTint.a = (unsigned char)((((float)color.a/255.0)*((float)tint.a/255.0))*255.0f);
|
colorTint.a = (unsigned char)((((float)color.a/255.0f)*((float)tint.a/255.0f))*255.0f);
|
||||||
|
|
||||||
model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = colorTint;
|
model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = colorTint;
|
||||||
DrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform);
|
DrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform);
|
||||||
|
|
@ -3640,31 +3640,12 @@ RayCollision GetRayCollisionMesh(Ray ray, Mesh mesh, Matrix transform)
|
||||||
return collision;
|
return collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get collision info between ray and model
|
|
||||||
RayCollision GetRayCollisionModel(Ray ray, Model model)
|
|
||||||
{
|
|
||||||
RayCollision collision = { 0 };
|
|
||||||
|
|
||||||
for (int m = 0; m < model.meshCount; m++)
|
|
||||||
{
|
|
||||||
RayCollision meshHitInfo = GetRayCollisionMesh(ray, model.meshes[m], model.transform);
|
|
||||||
|
|
||||||
if (meshHitInfo.hit)
|
|
||||||
{
|
|
||||||
// Save the closest hit mesh
|
|
||||||
if ((!collision.hit) || (collision.distance > meshHitInfo.distance)) collision = meshHitInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return collision;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get collision info between ray and triangle
|
// Get collision info between ray and triangle
|
||||||
// NOTE: The points are expected to be in counter-clockwise winding
|
// NOTE: The points are expected to be in counter-clockwise winding
|
||||||
// NOTE: Based on https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
|
// NOTE: Based on https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
|
||||||
RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
|
RayCollision GetRayCollisionTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
|
||||||
{
|
{
|
||||||
#define EPSILON 0.000001 // A small number
|
#define EPSILON 0.000001f // A small number
|
||||||
|
|
||||||
RayCollision collision = { 0 };
|
RayCollision collision = { 0 };
|
||||||
Vector3 edge1 = { 0 };
|
Vector3 edge1 = { 0 };
|
||||||
|
|
@ -4662,7 +4643,6 @@ static Model LoadGLTF(const char *fileName)
|
||||||
// Load our model data: meshes and materials
|
// Load our model data: meshes and materials
|
||||||
model.meshCount = primitivesCount;
|
model.meshCount = primitivesCount;
|
||||||
model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh));
|
model.meshes = RL_CALLOC(model.meshCount, sizeof(Mesh));
|
||||||
for (int i = 0; i < model.meshCount; i++) model.meshes[i].vboId = (unsigned int*)RL_CALLOC(MAX_MESH_VERTEX_BUFFERS, sizeof(unsigned int));
|
|
||||||
|
|
||||||
// NOTE: We keep an extra slot for default material, in case some mesh requires it
|
// NOTE: We keep an extra slot for default material, in case some mesh requires it
|
||||||
model.materialCount = (int)data->materials_count + 1;
|
model.materialCount = (int)data->materials_count + 1;
|
||||||
|
|
|
||||||
20
src/rtext.c
20
src/rtext.c
|
|
@ -25,7 +25,7 @@
|
||||||
*
|
*
|
||||||
* DEPENDENCIES:
|
* DEPENDENCIES:
|
||||||
* stb_truetype - Load TTF file and rasterize characters data
|
* stb_truetype - Load TTF file and rasterize characters data
|
||||||
* stb_rect_pack - Rectangles packing algorythms, required for font atlas generation
|
* stb_rect_pack - Rectangles packing algorithms, required for font atlas generation
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* LICENSE: zlib/libpng
|
* LICENSE: zlib/libpng
|
||||||
|
|
@ -229,7 +229,7 @@ extern void LoadFontDefault(void)
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Allocate space for our characters info data
|
// Allocate space for our characters info data
|
||||||
// NOTE: This memory should be freed at end! --> CloseWindow()
|
// NOTE: This memory must be freed at end! --> Done by CloseWindow()
|
||||||
defaultFont.glyphs = (GlyphInfo *)RL_MALLOC(defaultFont.glyphCount*sizeof(GlyphInfo));
|
defaultFont.glyphs = (GlyphInfo *)RL_MALLOC(defaultFont.glyphCount*sizeof(GlyphInfo));
|
||||||
defaultFont.recs = (Rectangle *)RL_MALLOC(defaultFont.glyphCount*sizeof(Rectangle));
|
defaultFont.recs = (Rectangle *)RL_MALLOC(defaultFont.glyphCount*sizeof(Rectangle));
|
||||||
|
|
||||||
|
|
@ -695,7 +695,7 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC
|
||||||
// DEBUG: We can see padding in the generated image setting a gray background...
|
// DEBUG: We can see padding in the generated image setting a gray background...
|
||||||
//for (int i = 0; i < atlas.width*atlas.height; i++) ((unsigned char *)atlas.data)[i] = 100;
|
//for (int i = 0; i < atlas.width*atlas.height; i++) ((unsigned char *)atlas.data)[i] = 100;
|
||||||
|
|
||||||
if (packMethod == 0) // Use basic packing algorythm
|
if (packMethod == 0) // Use basic packing algorithm
|
||||||
{
|
{
|
||||||
int offsetX = padding;
|
int offsetX = padding;
|
||||||
int offsetY = padding;
|
int offsetY = padding;
|
||||||
|
|
@ -746,7 +746,7 @@ Image GenImageFontAtlas(const GlyphInfo *chars, Rectangle **charRecs, int glyphC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (packMethod == 1) // Use Skyline rect packing algorythm (stb_pack_rect)
|
else if (packMethod == 1) // Use Skyline rect packing algorithm (stb_pack_rect)
|
||||||
{
|
{
|
||||||
stbrp_context *context = (stbrp_context *)RL_MALLOC(sizeof(*context));
|
stbrp_context *context = (stbrp_context *)RL_MALLOC(sizeof(*context));
|
||||||
stbrp_node *nodes = (stbrp_node *)RL_MALLOC(glyphCount*sizeof(*nodes));
|
stbrp_node *nodes = (stbrp_node *)RL_MALLOC(glyphCount*sizeof(*nodes));
|
||||||
|
|
@ -992,11 +992,11 @@ bool ExportFontAsCode(Font font, const char *fileName)
|
||||||
// NOTE: Uses default font
|
// NOTE: Uses default font
|
||||||
void DrawFPS(int posX, int posY)
|
void DrawFPS(int posX, int posY)
|
||||||
{
|
{
|
||||||
Color color = LIME; // good fps
|
Color color = LIME; // Good FPS
|
||||||
int fps = GetFPS();
|
int fps = GetFPS();
|
||||||
|
|
||||||
if (fps < 30 && fps >= 15) color = ORANGE; // warning FPS
|
if ((fps < 30) && (fps >= 15)) color = ORANGE; // Warning FPS
|
||||||
else if (fps < 15) color = RED; // bad FPS
|
else if (fps < 15) color = RED; // Low FPS
|
||||||
|
|
||||||
DrawText(TextFormat("%2i FPS", GetFPS()), posX, posY, 20, color);
|
DrawText(TextFormat("%2i FPS", GetFPS()), posX, posY, 20, color);
|
||||||
}
|
}
|
||||||
|
|
@ -1383,7 +1383,7 @@ const char *TextSubtext(const char *text, int position, int length)
|
||||||
|
|
||||||
// Replace text string
|
// Replace text string
|
||||||
// REQUIRES: strlen(), strstr(), strncpy(), strcpy()
|
// REQUIRES: strlen(), strstr(), strncpy(), strcpy()
|
||||||
// WARNING: Returned buffer must be freed by the user (if return != NULL)
|
// WARNING: Allocated memory must be manually freed
|
||||||
char *TextReplace(char *text, const char *replace, const char *by)
|
char *TextReplace(char *text, const char *replace, const char *by)
|
||||||
{
|
{
|
||||||
// Sanity checks and initialization
|
// Sanity checks and initialization
|
||||||
|
|
@ -1432,7 +1432,7 @@ char *TextReplace(char *text, const char *replace, const char *by)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert text in a specific position, moves all text forward
|
// Insert text in a specific position, moves all text forward
|
||||||
// WARNING: Allocated memory should be manually freed
|
// WARNING: Allocated memory must be manually freed
|
||||||
char *TextInsert(const char *text, const char *insert, int position)
|
char *TextInsert(const char *text, const char *insert, int position)
|
||||||
{
|
{
|
||||||
int textLen = TextLength(text);
|
int textLen = TextLength(text);
|
||||||
|
|
@ -1616,7 +1616,7 @@ const char *TextToPascal(const char *text)
|
||||||
|
|
||||||
// Encode text codepoint into UTF-8 text
|
// Encode text codepoint into UTF-8 text
|
||||||
// REQUIRES: memcpy()
|
// REQUIRES: memcpy()
|
||||||
// WARNING: Allocated memory should be manually freed
|
// WARNING: Allocated memory must be manually freed
|
||||||
char *TextCodepointsToUTF8(const int *codepoints, int length)
|
char *TextCodepointsToUTF8(const int *codepoints, int length)
|
||||||
{
|
{
|
||||||
// We allocate enough memory fo fit all possible codepoints
|
// We allocate enough memory fo fit all possible codepoints
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
* DEPENDENCIES:
|
* DEPENDENCIES:
|
||||||
* stb_image - Multiple image formats loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
|
* stb_image - Multiple image formats loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
|
||||||
* NOTE: stb_image has been slightly modified to support Android platform.
|
* NOTE: stb_image has been slightly modified to support Android platform.
|
||||||
* stb_image_resize - Multiple image resize algorythms
|
* stb_image_resize - Multiple image resize algorithms
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* LICENSE: zlib/libpng
|
* LICENSE: zlib/libpng
|
||||||
|
|
@ -306,10 +306,9 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
||||||
{
|
{
|
||||||
Image image = { 0 };
|
Image image = { 0 };
|
||||||
|
|
||||||
#if defined(SUPPORT_FILEFORMAT_PNG)
|
|
||||||
if ((strcmp(fileType, ".png") == 0)
|
|
||||||
#else
|
|
||||||
if ((false)
|
if ((false)
|
||||||
|
#if defined(SUPPORT_FILEFORMAT_PNG)
|
||||||
|
|| (strcmp(fileType, ".png") == 0)
|
||||||
#endif
|
#endif
|
||||||
#if defined(SUPPORT_FILEFORMAT_BMP)
|
#if defined(SUPPORT_FILEFORMAT_BMP)
|
||||||
|| (strcmp(fileType, ".bmp") == 0)
|
|| (strcmp(fileType, ".bmp") == 0)
|
||||||
|
|
@ -1890,10 +1889,10 @@ void ImageColorTint(Image *image, Color color)
|
||||||
unsigned char b = (unsigned char)(((float)pixels[index].b/255*cB)*255.0f);
|
unsigned char b = (unsigned char)(((float)pixels[index].b/255*cB)*255.0f);
|
||||||
unsigned char a = (unsigned char)(((float)pixels[index].a/255*cA)*255.0f);
|
unsigned char a = (unsigned char)(((float)pixels[index].a/255*cA)*255.0f);
|
||||||
|
|
||||||
pixels[y*image->width + x].r = r;
|
pixels[index].r = r;
|
||||||
pixels[y*image->width + x].g = g;
|
pixels[index].g = g;
|
||||||
pixels[y*image->width + x].b = b;
|
pixels[index].b = b;
|
||||||
pixels[y*image->width + x].a = a;
|
pixels[index].a = a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1959,25 +1958,25 @@ void ImageColorContrast(Image *image, float contrast)
|
||||||
for (int x = 0; x < image->width; x++)
|
for (int x = 0; x < image->width; x++)
|
||||||
{
|
{
|
||||||
float pR = (float)pixels[y*image->width + x].r/255.0f;
|
float pR = (float)pixels[y*image->width + x].r/255.0f;
|
||||||
pR -= 0.5;
|
pR -= 0.5f;
|
||||||
pR *= contrast;
|
pR *= contrast;
|
||||||
pR += 0.5;
|
pR += 0.5f;
|
||||||
pR *= 255;
|
pR *= 255;
|
||||||
if (pR < 0) pR = 0;
|
if (pR < 0) pR = 0;
|
||||||
if (pR > 255) pR = 255;
|
if (pR > 255) pR = 255;
|
||||||
|
|
||||||
float pG = (float)pixels[y*image->width + x].g/255.0f;
|
float pG = (float)pixels[y*image->width + x].g/255.0f;
|
||||||
pG -= 0.5;
|
pG -= 0.5f;
|
||||||
pG *= contrast;
|
pG *= contrast;
|
||||||
pG += 0.5;
|
pG += 0.5f;
|
||||||
pG *= 255;
|
pG *= 255;
|
||||||
if (pG < 0) pG = 0;
|
if (pG < 0) pG = 0;
|
||||||
if (pG > 255) pG = 255;
|
if (pG > 255) pG = 255;
|
||||||
|
|
||||||
float pB = (float)pixels[y*image->width + x].b/255.0f;
|
float pB = (float)pixels[y*image->width + x].b/255.0f;
|
||||||
pB -= 0.5;
|
pB -= 0.5f;
|
||||||
pB *= contrast;
|
pB *= contrast;
|
||||||
pB += 0.5;
|
pB += 0.5f;
|
||||||
pB *= 255;
|
pB *= 255;
|
||||||
if (pB < 0) pB = 0;
|
if (pB < 0) pB = 0;
|
||||||
if (pB > 255) pB = 255;
|
if (pB > 255) pB = 255;
|
||||||
|
|
@ -2412,7 +2411,20 @@ Color GetImageColor(Image image, int x, int y)
|
||||||
// Clear image background with given color
|
// Clear image background with given color
|
||||||
void ImageClearBackground(Image *dst, Color color)
|
void ImageClearBackground(Image *dst, Color color)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < dst->width*dst->height; ++i) ImageDrawPixel(dst, i%dst->width, i/dst->width, color);
|
// Security check to avoid program crash
|
||||||
|
if ((dst->data == NULL) || (dst->width == 0) || (dst->height == 0)) return;
|
||||||
|
|
||||||
|
// Fill in first pixel based on image format
|
||||||
|
ImageDrawPixel(dst, 0, 0, color);
|
||||||
|
|
||||||
|
unsigned char *pSrcPixel = (unsigned char *)dst->data;
|
||||||
|
int bytesPerPixel = GetPixelDataSize(1, 1, dst->format);
|
||||||
|
|
||||||
|
// Repeat the first pixel data throughout the image
|
||||||
|
for (int i = 1; i < dst->width * dst->height; i++)
|
||||||
|
{
|
||||||
|
memcpy(pSrcPixel + i * bytesPerPixel, pSrcPixel, bytesPerPixel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw pixel within an image
|
// Draw pixel within an image
|
||||||
|
|
@ -2686,13 +2698,21 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color)
|
||||||
int ey = sy + (int)rec.height;
|
int ey = sy + (int)rec.height;
|
||||||
|
|
||||||
int sx = (int)rec.x;
|
int sx = (int)rec.x;
|
||||||
int ex = sx + (int)rec.width;
|
|
||||||
|
int bytesPerPixel = GetPixelDataSize(1, 1, dst->format);
|
||||||
|
|
||||||
for (int y = sy; y < ey; y++)
|
for (int y = sy; y < ey; y++)
|
||||||
{
|
{
|
||||||
for (int x = sx; x < ex; x++)
|
// Fill in the first pixel of the row based on image format
|
||||||
|
ImageDrawPixel(dst, sx, y, color);
|
||||||
|
|
||||||
|
int bytesOffset = ((y * dst->width) + sx) * bytesPerPixel;
|
||||||
|
unsigned char *pSrcPixel = (unsigned char *)dst->data + bytesOffset;
|
||||||
|
|
||||||
|
// Repeat the first pixel data throughout the row
|
||||||
|
for (int x = 1; x < (int)rec.width; x++)
|
||||||
{
|
{
|
||||||
ImageDrawPixel(dst, x, y, color);
|
memcpy(pSrcPixel + x * bytesPerPixel, pSrcPixel, bytesPerPixel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3472,6 +3492,8 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle dest,
|
||||||
coordD.x = (nPatchInfo.source.x + nPatchInfo.source.width)/width;
|
coordD.x = (nPatchInfo.source.x + nPatchInfo.source.width)/width;
|
||||||
coordD.y = (nPatchInfo.source.y + nPatchInfo.source.height)/height;
|
coordD.y = (nPatchInfo.source.y + nPatchInfo.source.height)/height;
|
||||||
|
|
||||||
|
rlCheckRenderBatchLimit(9 * 3 * 2); // Maxium number of verts that could happen
|
||||||
|
|
||||||
rlSetTexture(texture.id);
|
rlSetTexture(texture.id);
|
||||||
|
|
||||||
rlPushMatrix();
|
rlPushMatrix();
|
||||||
|
|
|
||||||
21
src/switch-nx/dlfcn.h
Normal file
21
src/switch-nx/dlfcn.h
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
Required file to make miniaudio.h compile to Switch
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define RTLD_LAZY 0x00001
|
||||||
|
#define RTLD_NOW 0x00002
|
||||||
|
#define RTLD_BINDING_MASK 0x3
|
||||||
|
#define RTLD_NOLOAD 0x00004
|
||||||
|
#define RTLD_DEEPBIND 0x00008
|
||||||
|
#define RTLD_GLOBAL 0x00100
|
||||||
|
#define RTLD_LOCAL 0
|
||||||
|
#define RTLD_NODELETE 0x01000
|
||||||
|
|
||||||
|
void *dlopen(const char *, int);
|
||||||
|
void *dlsym(void *, const char *);
|
||||||
|
int dlclose(void *);
|
||||||
|
char *dlerror(void);
|
||||||
|
|
||||||
|
int pthread_attr_setschedpolicy(pthread_attr_t *, int) { return 0; }
|
||||||
|
int sched_get_priority_max(int policy) { return 0; }
|
||||||
|
int sched_get_priority_min(int policy) { return 0; }
|
||||||
46
src/utils.c
46
src/utils.c
|
|
@ -148,6 +148,7 @@ void TraceLog(int logType, const char *text, ...)
|
||||||
strcat(buffer, text);
|
strcat(buffer, text);
|
||||||
strcat(buffer, "\n");
|
strcat(buffer, "\n");
|
||||||
vprintf(buffer, args);
|
vprintf(buffer, args);
|
||||||
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
@ -268,6 +269,51 @@ bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite)
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Export data to code (.h), returns true on success
|
||||||
|
bool ExportDataAsCode(const char *data, unsigned int size, const char *fileName)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
#ifndef TEXT_BYTES_PER_LINE
|
||||||
|
#define TEXT_BYTES_PER_LINE 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NOTE: Text data buffer size is estimated considering raw data size in bytes
|
||||||
|
// and requiring 6 char bytes for every byte: "0x00, "
|
||||||
|
char *txtData = (char *)RL_CALLOC(size*6 + 2000, sizeof(char));
|
||||||
|
|
||||||
|
int byteCount = 0;
|
||||||
|
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// DataAsCode exporter v1.0 - Raw data exported as an array of bytes //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2022 Ramon Santamaria (@raysan5) //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "// //\n");
|
||||||
|
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n");
|
||||||
|
|
||||||
|
// Get file name from path and convert variable name to uppercase
|
||||||
|
char varFileName[256] = { 0 };
|
||||||
|
strcpy(varFileName, GetFileNameWithoutExt(fileName));
|
||||||
|
for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; }
|
||||||
|
|
||||||
|
byteCount += sprintf(txtData + byteCount, "static unsigned char %s_DATA[%i] = { ", varFileName, size);
|
||||||
|
for (int i = 0; i < size - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), data[i]);
|
||||||
|
byteCount += sprintf(txtData + byteCount, "0x%x };\n", data[size - 1]);
|
||||||
|
|
||||||
|
// NOTE: Text data size exported is determined by '\0' (NULL) character
|
||||||
|
success = SaveFileText(fileName, txtData);
|
||||||
|
|
||||||
|
RL_FREE(txtData);
|
||||||
|
|
||||||
|
if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Data as code exported successfully", fileName);
|
||||||
|
else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export data as code", fileName);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
// Load text data from file, returns a '\0' terminated string
|
// Load text data from file, returns a '\0' terminated string
|
||||||
// NOTE: text chars array should be freed manually
|
// NOTE: text chars array should be freed manually
|
||||||
char *LoadFileText(const char *fileName)
|
char *LoadFileText(const char *fileName)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user