Merge upstream
This commit is contained in:
commit
03534f2ec6
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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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-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 |
|
||||
| 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_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 |
|
||||
|
|
@ -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 |
|
||||
| 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-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
|
||||
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 |
|
||||
| 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 |
|
||||
| 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/kevinw/raylib-jai |
|
||||
| raylib-jai | 3.1-dev | [Jai](https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md) | https://github.com/kujukuju/raylib-jai |
|
||||
| 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 |
|
||||
| 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:
|
||||
|
||||
- [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>
|
||||
|
||||
[](https://github.com/raysan5/raylib/graphs/contributors)
|
||||
[](https://github.com/raysan5/raylib/releases)
|
||||
[](https://repology.org/project/raylib/versions)
|
||||
[](https://github.com/raysan5/raylib/graphs/contributors)
|
||||
[](https://github.com/raysan5/raylib/releases)
|
||||
[](https://github.com/raysan5/raylib/stargazers)
|
||||
[](https://github.com/raysan5/raylib/commits/master)
|
||||
[](https://repology.org/project/raylib/versions)
|
||||
[](LICENSE)
|
||||
|
||||
[](https://discord.gg/raylib)
|
||||
[](https://github.com/raysan5/raylib/stargazers)
|
||||
[](https://twitter.com/raysan5)
|
||||
[](https://www.reddit.com/r/raylib/)
|
||||
[](https://discord.gg/raylib)
|
||||
[](https://www.reddit.com/r/raylib/)
|
||||
[](https://www.youtube.com/c/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%3ALinux)
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ The following people are currently [**sponsoring raylib**](https://github.com/sp
|
|||
- Matthew Owens ([@MatthewOwens](https://github.com/MatthewOwens))
|
||||
- Tim Eilers ([@eilerstim](https://github.com/eilerstim))
|
||||
- Laurentino Luna ([@catmanl](https://github.com/catmanl))
|
||||
- ZimonIsHim ([@ZimonIsHim](https://github.com/ZimonIsHim))
|
||||
|
||||
### Past raylib GitHub Sponsors
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ elseif (${PLATFORM} MATCHES "Android")
|
|||
set(PLATFORM_CPP "PLATFORM_ANDROID")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
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)
|
||||
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")
|
||||
|
|
@ -87,7 +87,9 @@ endif ()
|
|||
|
||||
if (${OPENGL_VERSION})
|
||||
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")
|
||||
elseif (${OPENGL_VERSION} MATCHES "2.1")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_21")
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ endif
|
|||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# Libraries for Raspberry Pi compiling
|
||||
# NOTE: Required packages: libasound2-dev (ALSA)
|
||||
LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
|
||||
LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl -latomic
|
||||
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
|
||||
LDLIBS += -lvchiq_arm -lvcos
|
||||
endif
|
||||
|
|
@ -387,7 +387,7 @@ endif
|
|||
ifeq ($(PLATFORM),PLATFORM_DRM)
|
||||
# Libraries for DRM compiling
|
||||
# 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
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# Libraries for web (HTML5) compiling
|
||||
|
|
|
|||
|
|
@ -11,6 +11,49 @@
|
|||
|
||||
#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)
|
||||
{
|
||||
// Initialization
|
||||
|
|
@ -24,11 +67,18 @@ int main(void)
|
|||
|
||||
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);
|
||||
|
||||
float timePlayed = 0.0f;
|
||||
bool pause = false;
|
||||
|
||||
bool hasFilter = true;
|
||||
bool hasDelay = true;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -55,6 +105,22 @@ int main(void)
|
|||
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)
|
||||
timePlayed = GetMusicTimePlayed(music)/GetMusicTimeLength(music)*400;
|
||||
|
||||
|
|
@ -86,6 +152,8 @@ int main(void)
|
|||
|
||||
CloseAudioDevice(); // Close audio device (music streaming is automatically stopped)
|
||||
|
||||
RL_FREE(delayBuffer); // Free delay buffer
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,36 @@
|
|||
#define MAX_SAMPLES 512
|
||||
#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)
|
||||
{
|
||||
// Initialization
|
||||
|
|
@ -33,9 +63,11 @@ int main(void)
|
|||
|
||||
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);
|
||||
|
||||
SetAudioStreamCallback(stream, AudioInputCallback);
|
||||
|
||||
// Buffer for the single cycle waveform we are synthesizing
|
||||
short *data = (short *)malloc(sizeof(short)*MAX_SAMPLES);
|
||||
|
||||
|
|
@ -47,6 +79,7 @@ int main(void)
|
|||
// Position read in to determine next frequency
|
||||
Vector2 mousePosition = { -100.0f, -100.0f };
|
||||
|
||||
/*
|
||||
// Cycles per second (hz)
|
||||
float frequency = 440.0f;
|
||||
|
||||
|
|
@ -55,6 +88,7 @@ int main(void)
|
|||
|
||||
// Cursor to read and copy the samples of the sine wave buffer
|
||||
int readCursor = 0;
|
||||
*/
|
||||
|
||||
// Computed size in samples of the sine wave
|
||||
int waveLength = 1;
|
||||
|
|
@ -82,7 +116,7 @@ int main(void)
|
|||
SetAudioStreamPan(stream, pan);
|
||||
}
|
||||
|
||||
// Rewrite the sine wave.
|
||||
// Rewrite the sine wave
|
||||
// Compute two cycles to allow the buffer padding, simplifying any modulation, resampling, etc.
|
||||
if (frequency != oldFrequency)
|
||||
{
|
||||
|
|
@ -92,17 +126,18 @@ int main(void)
|
|||
if (waveLength > MAX_SAMPLES/2) waveLength = MAX_SAMPLES/2;
|
||||
if (waveLength < 1) waveLength = 1;
|
||||
|
||||
// Write sine wave.
|
||||
// Write sine wave
|
||||
for (int i = 0; i < waveLength*2; i++)
|
||||
{
|
||||
data[i] = (short)(sinf(((2*PI*(float)i/waveLength)))*32000);
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/*
|
||||
// Refill audio stream if required
|
||||
if (IsAudioStreamProcessed(stream))
|
||||
{
|
||||
|
|
@ -131,6 +166,7 @@ int main(void)
|
|||
// Copy finished frame to audio stream
|
||||
UpdateAudioStream(stream, writeBuf, MAX_SAMPLES_PER_UPDATE);
|
||||
}
|
||||
*/
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
|
|
|
|||
|
|
@ -92,20 +92,20 @@ int main(void)
|
|||
// Draw axis: left joystick
|
||||
DrawCircle(259, 152, 39, BLACK);
|
||||
DrawCircle(259, 152, 34, LIGHTGRAY);
|
||||
DrawCircle(259 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X)*20),
|
||||
152 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK);
|
||||
DrawCircle(259 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X)*20),
|
||||
152 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK);
|
||||
|
||||
// Draw axis: right joystick
|
||||
DrawCircle(461, 237, 38, BLACK);
|
||||
DrawCircle(461, 237, 33, LIGHTGRAY);
|
||||
DrawCircle(461 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*20),
|
||||
237 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
|
||||
DrawCircle(461 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*20),
|
||||
237 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(170, 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(604, 30, 15, (((1 + (int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER))/2)*70), RED);
|
||||
DrawRectangle(170, 30, 15, (int)(((1 + GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_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 RT: %02.02f", GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)), 10, 60, 10, BLACK);
|
||||
|
|
@ -140,20 +140,20 @@ int main(void)
|
|||
// Draw axis: left joystick
|
||||
DrawCircle(319, 255, 35, BLACK);
|
||||
DrawCircle(319, 255, 31, LIGHTGRAY);
|
||||
DrawCircle(319 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) * 20),
|
||||
255 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) * 20), 25, BLACK);
|
||||
DrawCircle(319 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) * 20),
|
||||
255 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) * 20), 25, BLACK);
|
||||
|
||||
// Draw axis: right joystick
|
||||
DrawCircle(475, 255, 35, BLACK);
|
||||
DrawCircle(475, 255, 31, LIGHTGRAY);
|
||||
DrawCircle(475 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*20),
|
||||
255 + ((int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
|
||||
DrawCircle(475 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X) * 20),
|
||||
255 + (int)(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y) * 20), 25, BLACK);
|
||||
|
||||
// Draw axis: left-right triggers
|
||||
DrawRectangle(169, 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(611, 48, 15, (((1 - (int)GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)) / 2) * 70), RED);
|
||||
DrawRectangle(169, 48, 15, (int)(((1 - GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_TRIGGER)) / 2) * 70), RED);
|
||||
DrawRectangle(611, 48, 15, (int)(((1 - GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_TRIGGER)) / 2) * 70), RED);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -78,7 +78,11 @@ int main(void)
|
|||
|
||||
// Initialize framebuffer for stereo rendering
|
||||
// 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
|
||||
Camera camera = { 0 };
|
||||
|
|
@ -121,8 +125,7 @@ int main(void)
|
|||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
BeginShaderMode(distortion);
|
||||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, (float)target.texture.width,
|
||||
(float)-target.texture.height }, (Vector2){ 0.0f, 0.0f }, WHITE);
|
||||
DrawTexturePro(target.texture, sourceRec, destRec, (Vector2){ 0.0f, 0.0f }, 0.0f, WHITE);
|
||||
EndShaderMode();
|
||||
DrawFPS(10, 10);
|
||||
EndDrawing();
|
||||
|
|
|
|||
|
|
@ -121,9 +121,22 @@ int main(void)
|
|||
cursorColor = ORANGE;
|
||||
hitObjectName = "Box";
|
||||
|
||||
// Check ray collision against model
|
||||
// NOTE: It considers model.transform matrix!
|
||||
RayCollision meshHitInfo = GetRayCollisionModel(ray, tower);
|
||||
// Check ray collision against model meshes
|
||||
RayCollision meshHitInfo = { 0 };
|
||||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ int main(void)
|
|||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - hot reloading");
|
||||
|
||||
|
|
|
|||
|
|
@ -217,6 +217,12 @@ int main(void)
|
|||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Free allocated matrices
|
||||
RL_FREE(rotations);
|
||||
RL_FREE(rotationsInc);
|
||||
RL_FREE(translations);
|
||||
RL_FREE(transforms);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ int main(void)
|
|||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [shaders] example - raymarching shapes");
|
||||
|
|
@ -77,9 +77,7 @@ int main(void)
|
|||
// Check if screen is resized
|
||||
if (IsWindowResized())
|
||||
{
|
||||
screenWidth = GetScreenWidth();
|
||||
screenHeight = GetScreenHeight();
|
||||
float resolution[2] = { (float)screenWidth, (float)screenHeight };
|
||||
float resolution[2] = { (float)GetScreenWidth(), (float)GetScreenHeight() };
|
||||
SetShaderValue(shader, resolutionLoc, resolution, SHADER_UNIFORM_VEC2);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -93,10 +91,10 @@ int main(void)
|
|||
// We only draw a white full-screen rectangle,
|
||||
// frame is generated in shader using raymarching
|
||||
BeginShaderMode(shader);
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, WHITE);
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), WHITE);
|
||||
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();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@ int main(void)
|
|||
//----------------------------------------------------------------------------------
|
||||
mousePosition = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointRec(mousePosition, rec) &&
|
||||
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 }))
|
||||
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 }))
|
||||
{
|
||||
mouseScaleReady = true;
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) mouseScaleMode = true;
|
||||
|
|
@ -56,8 +55,13 @@ int main(void)
|
|||
rec.width = (mousePosition.x - rec.x);
|
||||
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.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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ int main(int argc, char **argv)
|
|||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE); // Make the window resizable
|
||||
InitWindow(screenWidth, screenHeight, "raylib [textures] example - Draw part of a texture tiled");
|
||||
|
|
@ -71,9 +71,6 @@ int main(int argc, char **argv)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
screenWidth = GetScreenWidth();
|
||||
screenHeight = GetScreenHeight();
|
||||
|
||||
// Handle mouse
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
|
|
@ -122,11 +119,11 @@ int main(int argc, char **argv)
|
|||
ClearBackground(RAYWHITE);
|
||||
|
||||
// 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]);
|
||||
|
||||
// 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);
|
||||
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/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/physac.h -o physac_api.$(EXTENSION) -f $(FORMAT) -d PHYSACDEF
|
||||
./raylib_parser -i ../src/extras/raygui.h -o raygui_api.$(EXTENSION) -f $(FORMAT) -d RAYGUIAPI
|
||||
./raylib_parser -i ../src/extras/rmem.h -o rmem_api.$(EXTENSION) -f $(FORMAT) -d RMEMAPI
|
||||
./raylib_parser -i ../src/rlgl.h -o rlgl_api.$(EXTENSION) -f $(FORMAT) -d RLAPI
|
||||
./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 -t "RAYGUI IMPLEMENTATION"
|
||||
./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 -t "RLGL IMPLEMENTATION"
|
||||
|
||||
clean:
|
||||
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" ?>
|
||||
<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">
|
||||
<Struct name="Vector2" fieldCount="2" desc="Vector2, 2 components">
|
||||
<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="w" desc="Vector w component" />
|
||||
</Struct>
|
||||
<Struct name="Matrix" fieldCount="4" 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="m1, m5, m9, m13" desc="Matrix second row (4 components)" />
|
||||
<Field type="float" name="m2, m6, m10, m14" desc="Matrix third row (4 components)" />
|
||||
<Field type="float" name="m3, m7, m11, m15" desc="Matrix fourth row (4 components)" />
|
||||
<Struct name="Matrix" fieldCount="16" desc="Matrix, 4x4 components, column major, OpenGL style, right handed">
|
||||
<Field type="float" name="m0" desc="Matrix first row (4 components)" />
|
||||
<Field type="float" name="m4" desc="Matrix first row (4 components)" />
|
||||
<Field type="float" name="m8" desc="Matrix first 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 name="Color" fieldCount="4" desc="Color, 4 components, R8G8B8A8 (32bit)">
|
||||
<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="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="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="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)" />
|
||||
|
|
@ -118,7 +184,7 @@
|
|||
<Struct name="Material" fieldCount="3" desc="Material, includes shader and maps">
|
||||
<Field type="Shader" name="shader" desc="Material shader" />
|
||||
<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 name="Transform" fieldCount="3" desc="Transform, vectex transformation data">
|
||||
<Field type="Vector3" name="translation" desc="Translation" />
|
||||
|
|
@ -126,7 +192,7 @@
|
|||
<Field type="Vector3" name="scale" desc="Scale" />
|
||||
</Struct>
|
||||
<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" />
|
||||
</Struct>
|
||||
<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="void *" name="data" desc="Buffer data pointer" />
|
||||
</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="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="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, ...)" />
|
||||
|
|
@ -193,20 +260,27 @@
|
|||
<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="interpupillaryDistance" desc="IPD (distance between pupils) in meters" />
|
||||
<Field type="float" name="lensDistortionValues[4]" desc="Lens distortion constant parameters" />
|
||||
<Field type="float" name="chromaAbCorrection[4]" desc="Chromatic aberration correction parameters" />
|
||||
<Field type="float[4]" name="lensDistortionValues" desc="Lens distortion constant parameters" />
|
||||
<Field type="float[4]" name="chromaAbCorrection" desc="Chromatic aberration correction parameters" />
|
||||
</Struct>
|
||||
<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" name="viewOffset[2]" desc="VR view offset matrices (per eye)" />
|
||||
<Field type="float" name="leftLensCenter[2]" desc="VR left lens center" />
|
||||
<Field type="float" name="rightLensCenter[2]" desc="VR right lens center" />
|
||||
<Field type="float" name="leftScreenCenter[2]" desc="VR left screen center" />
|
||||
<Field type="float" name="rightScreenCenter[2]" desc="VR right screen center" />
|
||||
<Field type="float" name="scale[2]" desc="VR distortion scale" />
|
||||
<Field type="float" name="scaleIn[2]" desc="VR distortion scale in" />
|
||||
<Field type="Matrix[2]" name="projection" desc="VR projection matrices (per eye)" />
|
||||
<Field type="Matrix[2]" name="viewOffset" desc="VR view offset matrices (per eye)" />
|
||||
<Field type="float[2]" name="leftLensCenter" desc="VR left lens center" />
|
||||
<Field type="float[2]" name="rightLensCenter" desc="VR right lens center" />
|
||||
<Field type="float[2]" name="leftScreenCenter" desc="VR left screen center" />
|
||||
<Field type="float[2]" name="rightScreenCenter" desc="VR right screen center" />
|
||||
<Field type="float[2]" name="scale" desc="VR distortion scale" />
|
||||
<Field type="float[2]" name="scaleIn" desc="VR distortion scale in" />
|
||||
</Struct>
|
||||
</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">
|
||||
<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" />
|
||||
|
|
@ -543,61 +617,34 @@
|
|||
<Value name="NPATCH_THREE_PATCH_HORIZONTAL" integer="2" desc="Npatch layout: 3x1 tiles" />
|
||||
</Enum>
|
||||
</Enums>
|
||||
<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="UNKNOWN" value="(PI/180.0f)" desc="" />
|
||||
<Define name="RAD2DEG" type="UNKNOWN" 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>
|
||||
<Functions count="497">
|
||||
<Callbacks count="6">
|
||||
<Callback name="TraceLogCallback" retType="void" paramCount="3" desc="Logging: Redirect trace log messages">
|
||||
<Param type="int" name="logLevel" desc="" />
|
||||
<Param type="const char *" name="text" desc="" />
|
||||
<Param type="va_list" name="args" desc="" />
|
||||
</Callback>
|
||||
<Callback name="LoadFileDataCallback" retType="unsigned char *" paramCount="2" desc="FileIO: Load binary data">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
<Param type="unsigned int *" name="bytesRead" desc="" />
|
||||
</Callback>
|
||||
<Callback name="SaveFileDataCallback" retType="bool" paramCount="3" desc="FileIO: Save binary data">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
<Param type="void *" name="data" desc="" />
|
||||
<Param type="unsigned int" name="bytesToWrite" desc="" />
|
||||
</Callback>
|
||||
<Callback name="LoadFileTextCallback" retType="char *" paramCount="1" desc="FileIO: Load text data">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
</Callback>
|
||||
<Callback name="SaveFileTextCallback" retType="bool" paramCount="2" desc="FileIO: Save text data">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
<Param type="char *" name="text" desc="" />
|
||||
</Callback>
|
||||
<Callback name="AudioCallback" retType="void" paramCount="2" desc="">
|
||||
<Param type="void *" name="bufferData" desc="" />
|
||||
<Param type="unsigned int" name="frames" desc="" />
|
||||
</Callback>
|
||||
</Callbacks>
|
||||
<Functions count="499">
|
||||
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
||||
<Param type="int" name="width" desc="" />
|
||||
<Param type="int" name="height" desc="" />
|
||||
|
|
@ -955,7 +1002,7 @@
|
|||
</Function>
|
||||
<Function name="GetApplicationDirectory" retType="const char *" paramCount="0" desc="Get the directory if the running application (uses static string)">
|
||||
</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="int *" name="count" desc="" />
|
||||
</Function>
|
||||
|
|
@ -966,7 +1013,7 @@
|
|||
</Function>
|
||||
<Function name="IsFileDropped" retType="bool" paramCount="0" desc="Check if a file has been dropped into window">
|
||||
</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="" />
|
||||
</Function>
|
||||
<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)">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
</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="int" name="dataLength" desc="" />
|
||||
<Param type="int *" name="compDataLength" desc="" />
|
||||
<Param type="int" name="dataSize" desc="" />
|
||||
<Param type="int *" name="compDataSize" desc="" />
|
||||
</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="int" name="compDataLength" desc="" />
|
||||
<Param type="int *" name="dataLength" desc="" />
|
||||
<Param type="int" name="compDataSize" desc="" />
|
||||
<Param type="int *" name="dataSize" desc="" />
|
||||
</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="int" name="dataLength" desc="" />
|
||||
<Param type="int *" name="outputLength" desc="" />
|
||||
<Param type="int" name="dataSize" desc="" />
|
||||
<Param type="int *" name="outputSize" desc="" />
|
||||
</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="int *" name="outputLength" desc="" />
|
||||
<Param type="int *" name="outputSize" desc="" />
|
||||
</Function>
|
||||
<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="" />
|
||||
|
|
@ -2451,10 +2498,6 @@
|
|||
<Param type="Ray" name="ray" desc="" />
|
||||
<Param type="BoundingBox" name="box" desc="" />
|
||||
</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">
|
||||
<Param type="Ray" name="ray" 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">
|
||||
<Param type="int" name="size" desc="" />
|
||||
</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>
|
||||
</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+
|
||||
project(example)
|
||||
|
||||
# Generate compile_commands.json
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Dependencies
|
||||
find_package(raylib 4.0.0 QUIET) # QUIET or REQUIRED
|
||||
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:
|
||||
|
||||
``` bash
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
cmake -B build
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
### Web
|
||||
|
|
|
|||
21
src/Makefile
21
src/Makefile
|
|
@ -536,9 +536,15 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
|||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LDLIBS = -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
|
||||
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
|
||||
LDLIBS += -latomic
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_DRM)
|
||||
LDLIBS = -lGLESv2 -lEGL -ldrm -lgbm -lpthread -lrt -lm -ldl
|
||||
ifeq ($(RAYLIB_MODULE_AUDIO),TRUE)
|
||||
LDLIBS += -latomic
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_ANDROID)
|
||||
LDLIBS = -llog -landroid -lEGL -lGLESv2 -lOpenSLES -lc -lm
|
||||
|
|
@ -696,17 +702,26 @@ nxusb.o : nxusb.c nxusb.h raylib.h
|
|||
raygui.o : raygui.c
|
||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
||||
raygui.c:
|
||||
echo #define RAYGUI_IMPLEMENTATION > raygui.c
|
||||
echo #include "$(RAYLIB_MODULE_RAYGUI_PATH)/raygui.h" >> raygui.c
|
||||
ifeq ($(PLATFORM_SHELL), cmd)
|
||||
@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
|
||||
# NOTE: physac header should be distributed with raylib.h
|
||||
physac.o : physac.c
|
||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
||||
physac.c:
|
||||
ifeq ($(PLATFORM_SHELL), cmd)
|
||||
@echo #define PHYSAC_IMPLEMENTATION > 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
|
||||
android_native_app_glue.o : $(NATIVE_APP_GLUE)/android_native_app_glue.c
|
||||
$(CC) -c $< $(CFLAGS) $(INCLUDE_PATHS)
|
||||
|
|
|
|||
164
src/build.zig
164
src/build.zig
|
|
@ -1,89 +1,81 @@
|
|||
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 {
|
||||
// Standard release options allow the person running `zig build` to select
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||
const mode = b.standardReleaseOptions();
|
||||
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
|
||||
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
|
||||
const mode = b.standardReleaseOptions();
|
||||
|
||||
const raylib_flags = &[_][]const u8{
|
||||
"-std=gnu99",
|
||||
"-DPLATFORM_DESKTOP",
|
||||
"-DGL_SILENCE_DEPRECATION=199309L",
|
||||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891
|
||||
};
|
||||
|
||||
const raylib = b.addStaticLibrary("raylib", srcdir ++ "/raylib.h");
|
||||
raylib.setTarget(target);
|
||||
raylib.setBuildMode(mode);
|
||||
raylib.linkLibC();
|
||||
|
||||
raylib.addIncludeDir(srcdir ++ "/external/glfw/include");
|
||||
|
||||
raylib.addCSourceFiles(&.{
|
||||
srcdir ++ "/raudio.c",
|
||||
srcdir ++ "/rcore.c",
|
||||
srcdir ++ "/rmodels.c",
|
||||
srcdir ++ "/rshapes.c",
|
||||
srcdir ++ "/rtext.c",
|
||||
srcdir ++ "/rtextures.c",
|
||||
srcdir ++ "/utils.c",
|
||||
}, raylib_flags);
|
||||
|
||||
switch (raylib.target.toTarget().os.tag) {
|
||||
.windows => {
|
||||
raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags);
|
||||
raylib.linkSystemLibrary("winmm");
|
||||
raylib.linkSystemLibrary("gdi32");
|
||||
raylib.linkSystemLibrary("opengl32");
|
||||
raylib.addIncludeDir("external/glfw/deps/mingw");
|
||||
},
|
||||
.linux => {
|
||||
raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags);
|
||||
raylib.linkSystemLibrary("GL");
|
||||
raylib.linkSystemLibrary("rt");
|
||||
raylib.linkSystemLibrary("dl");
|
||||
raylib.linkSystemLibrary("m");
|
||||
raylib.linkSystemLibrary("X11");
|
||||
},
|
||||
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
||||
raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags);
|
||||
raylib.linkSystemLibrary("GL");
|
||||
raylib.linkSystemLibrary("rt");
|
||||
raylib.linkSystemLibrary("dl");
|
||||
raylib.linkSystemLibrary("m");
|
||||
raylib.linkSystemLibrary("X11");
|
||||
raylib.linkSystemLibrary("Xrandr");
|
||||
raylib.linkSystemLibrary("Xinerama");
|
||||
raylib.linkSystemLibrary("Xi");
|
||||
raylib.linkSystemLibrary("Xxf86vm");
|
||||
raylib.linkSystemLibrary("Xcursor");
|
||||
},
|
||||
.macos => {
|
||||
// On macos rglfw.c include Objective-C files.
|
||||
const raylib_flags_extra_macos = &[_][]const u8{
|
||||
"-ObjC",
|
||||
};
|
||||
raylib.addCSourceFiles(
|
||||
&.{srcdir ++ "/rglfw.c"},
|
||||
raylib_flags ++ raylib_flags_extra_macos,
|
||||
);
|
||||
raylib.linkFramework("Foundation");
|
||||
},
|
||||
else => {
|
||||
@panic("Unsupported OS");
|
||||
},
|
||||
}
|
||||
|
||||
raylib.setOutputDir("./");
|
||||
raylib.install();
|
||||
return raylib;
|
||||
}
|
||||
const raylib_flags = &[_][]const u8{
|
||||
"-std=gnu99",
|
||||
"-DPLATFORM_DESKTOP",
|
||||
"-DGL_SILENCE_DEPRECATION=199309L",
|
||||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/1891
|
||||
};
|
||||
}
|
||||
|
||||
const lib = Pkg(".");
|
||||
const raylib = b.addStaticLibrary("raylib", srcdir ++ "/raylib.h");
|
||||
raylib.setTarget(target);
|
||||
raylib.setBuildMode(mode);
|
||||
raylib.linkLibC();
|
||||
|
||||
raylib.addIncludeDir(srcdir ++ "/external/glfw/include");
|
||||
|
||||
raylib.addCSourceFiles(&.{
|
||||
srcdir ++ "/raudio.c",
|
||||
srcdir ++ "/rcore.c",
|
||||
srcdir ++ "/rmodels.c",
|
||||
srcdir ++ "/rshapes.c",
|
||||
srcdir ++ "/rtext.c",
|
||||
srcdir ++ "/rtextures.c",
|
||||
srcdir ++ "/utils.c",
|
||||
}, raylib_flags);
|
||||
|
||||
switch (raylib.target.toTarget().os.tag) {
|
||||
.windows => {
|
||||
raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags);
|
||||
raylib.linkSystemLibrary("winmm");
|
||||
raylib.linkSystemLibrary("gdi32");
|
||||
raylib.linkSystemLibrary("opengl32");
|
||||
raylib.addIncludeDir("external/glfw/deps/mingw");
|
||||
},
|
||||
.linux => {
|
||||
raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags);
|
||||
raylib.linkSystemLibrary("GL");
|
||||
raylib.linkSystemLibrary("rt");
|
||||
raylib.linkSystemLibrary("dl");
|
||||
raylib.linkSystemLibrary("m");
|
||||
raylib.linkSystemLibrary("X11");
|
||||
},
|
||||
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
||||
raylib.addCSourceFiles(&.{srcdir ++ "/rglfw.c"}, raylib_flags);
|
||||
raylib.linkSystemLibrary("GL");
|
||||
raylib.linkSystemLibrary("rt");
|
||||
raylib.linkSystemLibrary("dl");
|
||||
raylib.linkSystemLibrary("m");
|
||||
raylib.linkSystemLibrary("X11");
|
||||
raylib.linkSystemLibrary("Xrandr");
|
||||
raylib.linkSystemLibrary("Xinerama");
|
||||
raylib.linkSystemLibrary("Xi");
|
||||
raylib.linkSystemLibrary("Xxf86vm");
|
||||
raylib.linkSystemLibrary("Xcursor");
|
||||
},
|
||||
.macos => {
|
||||
// On macos rglfw.c include Objective-C files.
|
||||
const raylib_flags_extra_macos = &[_][]const u8{
|
||||
"-ObjC",
|
||||
};
|
||||
raylib.addCSourceFiles(
|
||||
&.{srcdir ++ "/rglfw.c"},
|
||||
raylib_flags ++ raylib_flags_extra_macos,
|
||||
);
|
||||
raylib.linkFramework("Foundation");
|
||||
},
|
||||
else => {
|
||||
@panic("Unsupported OS");
|
||||
},
|
||||
}
|
||||
|
||||
return raylib;
|
||||
}
|
||||
|
||||
pub fn build(b: *std.build.Builder) void {
|
||||
// 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.
|
||||
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 ".";
|
||||
}
|
||||
|
|
|
|||
34535
src/external/miniaudio.h
vendored
34535
src/external/miniaudio.h
vendored
File diff suppressed because it is too large
Load Diff
|
|
@ -101,47 +101,47 @@ extern "C" { // Prevents name mangling of functions
|
|||
#endif
|
||||
|
||||
// Linear Easing functions
|
||||
EASEDEF float EaseLinearNone(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); }
|
||||
EASEDEF float EaseLinearOut(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); }
|
||||
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); } // Ease: Linear In
|
||||
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); } // Ease: Linear In Out
|
||||
|
||||
// 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 EaseSineOut(float t, float b, float c, float d) { return (c*sinf(t/d*(PI/2.0f)) + b); }
|
||||
EASEDEF float EaseSineInOut(float t, float b, float c, float d) { return (-c/2.0f*(cosf(PI*t/d) - 1.0f) + 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); } // 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); } // Ease: Sine Out
|
||||
|
||||
// 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 EaseCircOut(float t, float b, float c, float d) { t = t/d - 1.0f; return (c*sqrtf(1.0f - t*t) + b); }
|
||||
EASEDEF float EaseCircInOut(float t, float b, float c, float d)
|
||||
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); } // Ease: Circular Out
|
||||
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);
|
||||
t -= 2.0f; return (c/2.0f*(sqrtf(1.0f - t*t) + 1.0f) + b);
|
||||
}
|
||||
|
||||
// Cubic Easing functions
|
||||
EASEDEF float EaseCubicIn(float t, float b, float c, float d) { t /= d; return (c*t*t*t + 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); }
|
||||
EASEDEF float EaseCubicInOut(float t, float b, float c, float d)
|
||||
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); } // Ease: Cubic Out
|
||||
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);
|
||||
t -= 2.0f; return (c/2.0f*(t*t*t + 2.0f) + b);
|
||||
}
|
||||
|
||||
// Quadratic Easing functions
|
||||
EASEDEF float EaseQuadIn(float t, float b, float c, float d) { t /= d; return (c*t*t + b); }
|
||||
EASEDEF float EaseQuadOut(float t, float b, float c, float d) { t /= d; return (-c*t*(t - 2.0f) + b); }
|
||||
EASEDEF float EaseQuadInOut(float t, float b, float c, float d)
|
||||
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); } // Ease: Quadratic Out
|
||||
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);
|
||||
return (-c/2.0f*(((t - 1.0f)*(t - 3.0f)) - 1.0f) + b);
|
||||
}
|
||||
|
||||
// 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 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 EaseExpoInOut(float t, float b, float c, float d)
|
||||
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); } // Ease: Exponential Out
|
||||
EASEDEF float EaseExpoInOut(float t, float b, float c, float d) // Ease: Exponential In Out
|
||||
{
|
||||
if (t == 0.0f) return b;
|
||||
if (t == d) return (b + c);
|
||||
|
|
@ -151,21 +151,21 @@ EASEDEF float EaseExpoInOut(float t, float b, float c, float d)
|
|||
}
|
||||
|
||||
// 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 postFix = t/=d;
|
||||
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;
|
||||
t = t/d - 1.0f;
|
||||
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;
|
||||
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
|
||||
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))
|
||||
{
|
||||
|
|
@ -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 EaseBounceInOut(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); } // Ease: Bounce In
|
||||
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);
|
||||
else return (EaseBounceOut(t*2.0f - d, 0.0f, c, d)*0.5f + c*0.5f + b);
|
||||
}
|
||||
|
||||
// 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/=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);
|
||||
}
|
||||
|
||||
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/=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);
|
||||
}
|
||||
|
||||
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/=d/2.0f) == 2.0f) return (b + c);
|
||||
|
|
|
|||
|
|
@ -1999,7 +1999,6 @@ bool GuiTextBox(Rectangle bounds, char *text, int textSize, bool editMode)
|
|||
{
|
||||
keyCount--;
|
||||
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--;
|
||||
textValue[keyCount] = '\0';
|
||||
if (keyCount < 0) keyCount = 0;
|
||||
valueHasChanged = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
178
src/raudio.c
178
src/raudio.c
|
|
@ -247,10 +247,6 @@ typedef struct tagBITMAPINFOHEADER {
|
|||
#include "external/dr_flac.h" // FLAC loading functions
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#undef bool
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -311,10 +307,13 @@ typedef enum {
|
|||
AUDIO_BUFFER_USAGE_STREAM
|
||||
} AudioBufferUsage;
|
||||
|
||||
// Audio buffer structure
|
||||
// Audio buffer struct
|
||||
struct rAudioBuffer {
|
||||
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 pitch; // Audio buffer pitch
|
||||
float pan; // Audio buffer pan (0.0f to 1.0f)
|
||||
|
|
@ -335,6 +334,14 @@ struct rAudioBuffer {
|
|||
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
|
||||
|
||||
// Audio data context
|
||||
|
|
@ -372,7 +379,7 @@ static AudioData AUDIO = { // Global AUDIO context
|
|||
//----------------------------------------------------------------------------------
|
||||
// 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 MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 frameCount, AudioBuffer *buffer);
|
||||
|
||||
|
|
@ -411,7 +418,7 @@ void InitAudioDevice(void)
|
|||
{
|
||||
// Init audio context
|
||||
ma_context_config ctxConfig = ma_context_config_init();
|
||||
ctxConfig.logCallback = OnLog;
|
||||
ma_log_callback_init(OnLog, NULL);
|
||||
|
||||
ma_result result = ma_context_init(NULL, 0, &ctxConfig, &AUDIO.System.context);
|
||||
if (result != MA_SUCCESS)
|
||||
|
|
@ -465,8 +472,7 @@ void InitAudioDevice(void)
|
|||
// Init dummy audio buffers pool for multichannel sound playing
|
||||
for (int i = 0; i < MAX_AUDIO_BUFFER_POOL_CHANNELS; i++)
|
||||
{
|
||||
// WARNING: An empty audio buffer is created (data = 0)
|
||||
// AudioBuffer data just points to loaded sound data
|
||||
// WARNING: An empty audio buffer is created (data = 0) and added to list, AudioBuffer data is filled on PlaySoundMulti()
|
||||
AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO.System.device.sampleRate, 0, AUDIO_BUFFER_USAGE_STATIC);
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +498,7 @@ void CloseAudioDevice(void)
|
|||
//UnloadAudioBuffer(AUDIO.MultiChannel.pool[i]);
|
||||
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]);
|
||||
//RL_FREE(buffer->data); // Already unloaded by UnloadSound()
|
||||
RL_FREE(AUDIO.MultiChannel.pool[i]);
|
||||
|
|
@ -541,9 +547,9 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
|
|||
|
||||
// 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);
|
||||
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)
|
||||
{
|
||||
|
|
@ -557,9 +563,13 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
|
|||
audioBuffer->pitch = 1.0f;
|
||||
audioBuffer->pan = 0.5f;
|
||||
|
||||
audioBuffer->callback = NULL;
|
||||
audioBuffer->processor = NULL;
|
||||
|
||||
audioBuffer->playing = false;
|
||||
audioBuffer->paused = false;
|
||||
audioBuffer->looping = false;
|
||||
|
||||
audioBuffer->usage = usage;
|
||||
audioBuffer->frameCursorPos = 0;
|
||||
audioBuffer->sizeInFrames = sizeInFrames;
|
||||
|
|
@ -580,7 +590,7 @@ void UnloadAudioBuffer(AudioBuffer *buffer)
|
|||
{
|
||||
if (buffer != NULL)
|
||||
{
|
||||
ma_data_converter_uninit(&buffer->converter);
|
||||
ma_data_converter_uninit(&buffer->converter, NULL);
|
||||
UntrackAudioBuffer(buffer);
|
||||
RL_FREE(buffer->data);
|
||||
RL_FREE(buffer);
|
||||
|
|
@ -654,8 +664,8 @@ void SetAudioBufferPitch(AudioBuffer *buffer, float pitch)
|
|||
// Note that this changes the duration of the sound:
|
||||
// - higher pitches will make the sound faster
|
||||
// - lower pitches make it slower
|
||||
ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.config.sampleRateOut/pitch);
|
||||
ma_data_converter_set_rate(&buffer->converter, buffer->converter.config.sampleRateIn, outputSampleRate);
|
||||
ma_uint32 outputSampleRate = (ma_uint32)((float)buffer->converter.sampleRateOut/pitch);
|
||||
ma_data_converter_set_rate(&buffer->converter, buffer->converter.sampleRateIn, outputSampleRate);
|
||||
|
||||
buffer->pitch = pitch;
|
||||
}
|
||||
|
|
@ -894,7 +904,7 @@ void UpdateSound(Sound sound, const void *data, int sampleCount)
|
|||
StopAudioBuffer(sound.stream.buffer);
|
||||
|
||||
// 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 +1078,8 @@ void PlaySoundMulti(Sound sound)
|
|||
AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[0] = false;
|
||||
AUDIO.MultiChannel.pool[index]->isSubBufferProcessed[1] = false;
|
||||
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]);
|
||||
}
|
||||
|
|
@ -1191,8 +1202,7 @@ Wave WaveCopy(Wave wave)
|
|||
// NOTE: Security check in case of out-of-range
|
||||
void WaveCrop(Wave *wave, int initSample, int finalSample)
|
||||
{
|
||||
if ((initSample >= 0) && (initSample < finalSample) &&
|
||||
(finalSample > 0) && ((unsigned int)finalSample < (wave->frameCount*wave->channels)))
|
||||
if ((initSample >= 0) && (initSample < finalSample) && ((unsigned int)finalSample < (wave->frameCount*wave->channels)))
|
||||
{
|
||||
int sampleCount = finalSample - initSample;
|
||||
|
||||
|
|
@ -1503,16 +1513,14 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
|||
jar_xm_set_max_loop_count(ctxXm, 0); // Set infinite number of loops
|
||||
|
||||
unsigned int bits = 32;
|
||||
if (AUDIO_DEVICE_FORMAT == ma_format_s16)
|
||||
bits = 16;
|
||||
else if (AUDIO_DEVICE_FORMAT == ma_format_u8)
|
||||
bits = 8;
|
||||
if (AUDIO_DEVICE_FORMAT == ma_format_s16) bits = 16;
|
||||
else if (AUDIO_DEVICE_FORMAT == ma_format_u8) bits = 8;
|
||||
|
||||
// NOTE: Only stereo is supported for XM
|
||||
music.stream = LoadAudioStream(AUDIO.System.device.sampleRate, bits, 2);
|
||||
music.frameCount = (unsigned int)jar_xm_get_remaining_samples(ctxXm); // NOTE: Always 2 channels (stereo)
|
||||
music.looping = true; // Looping enabled by default
|
||||
jar_xm_reset(ctxXm); // make sure we start at the beginning of the song
|
||||
jar_xm_reset(ctxXm); // make sure we start at the beginning of the song
|
||||
|
||||
music.ctxData = ctxXm;
|
||||
musicLoaded = true;
|
||||
|
|
@ -1533,7 +1541,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, const unsigned char *data,
|
|||
for (int i = 0; i < it; i++) newData[i] = data[i];
|
||||
|
||||
// Memory loaded version for jar_mod_load_file()
|
||||
if (dataSize && dataSize < 32*1024*1024)
|
||||
if (dataSize && (dataSize < 32*1024*1024))
|
||||
{
|
||||
ctxMod->modfilesize = dataSize;
|
||||
ctxMod->modfile = newData;
|
||||
|
|
@ -2028,22 +2036,86 @@ void SetAudioStreamBufferSizeDefault(int 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
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// 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;
|
||||
(void)pDevice;
|
||||
|
||||
TRACELOG(LOG_WARNING, "miniaudio: %s", message); // All log messages from miniaudio are errors
|
||||
TRACELOG(LOG_WARNING, "miniaudio: %s", pMessage); // All log messages from miniaudio are errors
|
||||
}
|
||||
|
||||
// Reads audio data from an AudioBuffer object in internal format.
|
||||
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 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames;
|
||||
|
||||
|
|
@ -2055,7 +2127,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer,
|
|||
isSubBufferProcessed[0] = audioBuffer->isSubBufferProcessed[0];
|
||||
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
|
||||
ma_uint32 framesRead = 0;
|
||||
|
|
@ -2135,20 +2207,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
|
||||
// frames. This can be achieved with ma_data_converter_get_required_input_frame_count().
|
||||
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;
|
||||
while (totalOutputFramesProcessed < frameCount)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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. */
|
||||
ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */
|
||||
|
|
@ -2217,6 +2290,14 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
|
|||
float *framesOut = (float *)pFramesOut + (framesRead*AUDIO.System.device.playback.channels);
|
||||
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);
|
||||
|
||||
framesToRead -= framesJustRead;
|
||||
|
|
@ -2257,41 +2338,44 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const
|
|||
ma_mutex_unlock(&AUDIO.System.lock);
|
||||
}
|
||||
|
||||
// This is the main mixing function. Mixing is pretty simple in this project - it's just an accumulation.
|
||||
// NOTE: framesOut is both an input and an output. It will be initially filled with zeros outside of this function.
|
||||
// Main mixing function, pretty simple in this project, just an accumulation
|
||||
// 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)
|
||||
{
|
||||
const float localVolume = buffer->volume;
|
||||
const ma_uint32 channels = AUDIO.System.device.playback.channels;
|
||||
|
||||
const ma_uint32 nChannels = AUDIO.System.device.playback.channels;
|
||||
if (nChannels == 2)
|
||||
if (channels == 2) // We consider panning
|
||||
{
|
||||
const float left = buffer->pan;
|
||||
const float right = 1.0f - left;
|
||||
|
||||
// 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) };
|
||||
// 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) };
|
||||
|
||||
float *frameOut = framesOut;
|
||||
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[1] += (frameIn[1]*levels[1]);
|
||||
|
||||
frameOut += 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);
|
||||
const float *frameIn = framesIn + (iFrame * nChannels);
|
||||
float *frameOut = framesOut + (frame*channels);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
src/raylib.h
40
src/raylib.h
|
|
@ -33,8 +33,8 @@
|
|||
*
|
||||
* OPTIONAL DEPENDENCIES (included):
|
||||
* [rcore] msf_gif (Miles Fogle) for GIF recording
|
||||
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorythm
|
||||
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorythm
|
||||
* [rcore] sinfl (Micha Mettke) for DEFLATE decompression algorithm
|
||||
* [rcore] sdefl (Micha Mettke) for DEFLATE compression algorithm
|
||||
* [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_resize (Sean Barret) for image resizing algorithms
|
||||
|
|
@ -177,10 +177,10 @@
|
|||
// Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Boolean type
|
||||
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool)
|
||||
typedef enum bool { false, true } bool;
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#define RL_BOOL_TYPE
|
||||
#endif
|
||||
|
||||
|
|
@ -322,7 +322,7 @@ typedef struct Mesh {
|
|||
// Vertex attributes data
|
||||
float *vertices; // Vertex position (XYZ - 3 components per vertex) (shader-location = 0)
|
||||
float *texcoords; // Vertex texture coordinates (UV - 2 components per vertex) (shader-location = 1)
|
||||
float *texcoords2; // Vertex second texture coordinates (useful for lightmaps) (shader-location = 5)
|
||||
float *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 *tangents; // Vertex tangents (XYZW - 4 components per vertex) (shader-location = 4)
|
||||
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
|
||||
} Wave;
|
||||
|
||||
// Opaque structs declaration
|
||||
// NOTE: Actual structs are defined internally in raudio module
|
||||
typedef struct rAudioBuffer rAudioBuffer;
|
||||
typedef struct rAudioProcessor rAudioProcessor;
|
||||
|
||||
// AudioStream, custom audio stream
|
||||
typedef struct AudioStream {
|
||||
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 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 void SetClipboardText(const char *text); // Set 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
|
||||
// NOTE: Those functions are intended for advance users that want full control over the frame processing
|
||||
|
|
@ -1033,9 +1039,10 @@ RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom
|
|||
RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver
|
||||
|
||||
// Files management functions
|
||||
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 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 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
|
||||
|
|
@ -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 *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 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 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 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 long GetFileModTime(const char *fileName); // Get file modification time (last write time)
|
||||
|
||||
// Compression/Encoding functionality
|
||||
RLAPI unsigned char *CompressData(const unsigned char *data, int dataLength, int *compDataLength); // Compress data (DEFLATE algorithm)
|
||||
RLAPI unsigned char *DecompressData(const unsigned char *compData, int compDataLength, int *dataLength); // Decompress data (DEFLATE algorithm)
|
||||
RLAPI char *EncodeDataBase64(const unsigned char *data, int dataLength, int *outputLength); // Encode data to Base64 string
|
||||
RLAPI unsigned char *DecodeDataBase64(const unsigned char *data, int *outputLength); // Decode Base64 string data
|
||||
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 compDataSize, int *dataSize); // Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||
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 *outputSize); // Decode Base64 string data, memory must be MemFree()
|
||||
|
||||
// Persistent storage management
|
||||
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 bool ExportFontAsCode(Font font, const char *fileName); // Export font as code file, returns true on success
|
||||
|
||||
|
||||
// Text drawing functions
|
||||
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)
|
||||
|
|
@ -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 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 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 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
|
||||
|
|
@ -1473,6 +1478,7 @@ RLAPI RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3
|
|||
//------------------------------------------------------------------------------------
|
||||
// Audio Loading and Playing Functions (Module: audio)
|
||||
//------------------------------------------------------------------------------------
|
||||
typedef void (*AudioCallback)(void *bufferData, unsigned int frames);
|
||||
|
||||
// Audio device management functions
|
||||
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 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 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)
|
||||
}
|
||||
|
|
|
|||
242
src/raymath.h
242
src/raymath.h
|
|
@ -18,7 +18,7 @@
|
|||
* - Functions are always self-contained, no function use another raymath function inside,
|
||||
* required code is directly re-implemented inside
|
||||
* - 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
|
||||
* - Angles are always in radians (DEG2RAD/RAD2DEG macros provided for convenience)
|
||||
*
|
||||
|
|
@ -77,6 +77,10 @@
|
|||
#define PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
#ifndef EPSILON
|
||||
#define EPSILON 0.000001f
|
||||
#endif
|
||||
|
||||
#ifndef DEG2RAD
|
||||
#define DEG2RAD (PI/180.0f)
|
||||
#endif
|
||||
|
|
@ -194,6 +198,14 @@ RMAPI float Remap(float value, float inputStart, float inputEnd, float outputSta
|
|||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -345,16 +357,16 @@ RMAPI Vector2 Vector2Normalize(Vector2 v)
|
|||
// Transforms a Vector2 by a given Matrix
|
||||
RMAPI Vector2 Vector2Transform(Vector2 v, Matrix mat)
|
||||
{
|
||||
Vector2 result = { 0 };
|
||||
Vector2 result = { 0 };
|
||||
|
||||
float x = v.x;
|
||||
float y = v.y;
|
||||
float z = 0;
|
||||
float x = v.x;
|
||||
float y = v.y;
|
||||
float z = 0;
|
||||
|
||||
result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
|
||||
result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
|
||||
result.x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12;
|
||||
result.y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13;
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate linear interpolation between two vectors
|
||||
|
|
@ -414,6 +426,62 @@ RMAPI Vector2 Vector2MoveTowards(Vector2 v, Vector2 target, float maxDistance)
|
|||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -498,14 +566,14 @@ RMAPI Vector3 Vector3Perpendicular(Vector3 v)
|
|||
float min = (float) fabs(v.x);
|
||||
Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
|
||||
|
||||
if (fabs(v.y) < min)
|
||||
if (fabsf(v.y) < min)
|
||||
{
|
||||
min = (float) fabs(v.y);
|
||||
Vector3 tmp = {0.0f, 1.0f, 0.0f};
|
||||
cardinalAxis = tmp;
|
||||
}
|
||||
|
||||
if (fabs(v.z) < min)
|
||||
if (fabsf(v.z) < min)
|
||||
{
|
||||
Vector3 tmp = {0.0f, 0.0f, 1.0f};
|
||||
cardinalAxis = tmp;
|
||||
|
|
@ -851,6 +919,92 @@ RMAPI float3 Vector3ToFloatV(Vector3 v)
|
|||
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
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -956,45 +1110,6 @@ RMAPI Matrix MatrixInvert(Matrix mat)
|
|||
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
|
||||
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;
|
||||
|
||||
if (lengthSq != 0.0)
|
||||
if (lengthSq != 0.0f)
|
||||
{
|
||||
float invLength = 1.0f/lengthSq;
|
||||
|
||||
|
|
@ -1550,12 +1665,10 @@ RMAPI Quaternion QuaternionScale(Quaternion q, float mul)
|
|||
{
|
||||
Quaternion result = { 0 };
|
||||
|
||||
float qax = q.x, qay = q.y, qaz = q.z, qaw = q.w;
|
||||
|
||||
result.x = qax*mul + qaw*mul + qay*mul - qaz*mul;
|
||||
result.y = qay*mul + qaw*mul + qaz*mul - qax*mul;
|
||||
result.z = qaz*mul + qaw*mul + qax*mul - qay*mul;
|
||||
result.w = qaw*mul - qax*mul - qay*mul - qaz*mul;
|
||||
result.x = q.x*mul;
|
||||
result.y = q.y*mul;
|
||||
result.z = q.z*mul;
|
||||
result.w = q.w*mul;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -1619,14 +1732,14 @@ RMAPI Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
|
|||
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
|
||||
{
|
||||
float halfTheta = acosf(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.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
|
||||
RMAPI void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
|
||||
{
|
||||
if (fabs(q.w) > 1.0f)
|
||||
if (fabsf(q.w) > 1.0f)
|
||||
{
|
||||
// QuaternionNormalize(q);
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
|||
286
src/rcore.c
286
src/rcore.c
|
|
@ -184,7 +184,7 @@
|
|||
|
||||
#include <stdlib.h> // Required for: srand(), rand(), atexit()
|
||||
#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 <math.h> // Required for: tan() [Used in BeginMode3D()], atan2f() [Used in LoadVrStereoConfig()]
|
||||
|
||||
|
|
@ -227,7 +227,7 @@
|
|||
unsigned int __stdcall timeEndPeriod(unsigned int uPeriod);
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#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
|
||||
|
|
@ -247,6 +247,7 @@
|
|||
//#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_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 <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 shouldClose; // Check if window set for closing
|
||||
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)
|
||||
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;
|
||||
|
||||
// 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.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||
CORE.Input.Gamepad.lastButtonPressed = -1;
|
||||
#if defined(SUPPORT_EVENTS_WAITING)
|
||||
CORE.Window.eventWaiting = true;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
CORE.Window.screen.width = width;
|
||||
|
|
@ -1211,39 +1217,39 @@ bool IsWindowState(unsigned int flag)
|
|||
void ToggleFullscreen(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// NOTE: glfwSetWindowMonitor() doesn't work properly (bugs)
|
||||
// TODO: glfwSetWindowMonitor() doesn't work properly (bugs)
|
||||
if (!CORE.Window.fullscreen)
|
||||
{
|
||||
// Store previous window position (in case we exit fullscreen)
|
||||
glfwGetWindowPos(CORE.Window.handle, &CORE.Window.position.x, &CORE.Window.position.y);
|
||||
|
||||
int monitorCount = 0;
|
||||
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount);
|
||||
|
||||
int monitorIndex = GetCurrentMonitor();
|
||||
GLFWmonitor **monitors = glfwGetMonitors(&monitorCount);
|
||||
|
||||
// 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");
|
||||
|
||||
CORE.Window.fullscreen = false; // Toggle fullscreen flag
|
||||
CORE.Window.fullscreen = false;
|
||||
CORE.Window.flags &= ~FLAG_FULLSCREEN_MODE;
|
||||
|
||||
glfwSetWindowMonitor(CORE.Window.handle, NULL, 0, 0, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
CORE.Window.fullscreen = true; // Toggle fullscreen flag
|
||||
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
|
||||
{
|
||||
CORE.Window.fullscreen = false; // Toggle fullscreen flag
|
||||
CORE.Window.fullscreen = false;
|
||||
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);
|
||||
|
|
@ -1934,6 +1940,29 @@ const char *GetMonitorName(int monitor)
|
|||
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
|
||||
// NOTE: returned string is allocated and freed by GLFW
|
||||
const char *GetClipboardText(void)
|
||||
|
|
@ -1947,16 +1976,7 @@ const char *GetClipboardText(void)
|
|||
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
|
||||
void ShowCursor(void)
|
||||
|
|
@ -2066,8 +2086,9 @@ void EndDrawing(void)
|
|||
{
|
||||
// Get image data for the current frame (from backbuffer)
|
||||
// NOTE: This process is quite slow... :(
|
||||
unsigned char *screenData = rlReadScreenPixels(CORE.Window.screen.width, CORE.Window.screen.height);
|
||||
msf_gif_frame(&gifState, screenData, 10, 16, CORE.Window.screen.width*4);
|
||||
Vector2 scale = GetWindowScaleDPI();
|
||||
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
|
||||
}
|
||||
|
|
@ -2236,8 +2257,10 @@ void BeginTextureMode(RenderTexture2D 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);
|
||||
rlSetFramebufferWidth(target.texture.width);
|
||||
rlSetFramebufferHeight(target.texture.height);
|
||||
|
||||
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||
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)
|
||||
// ...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*(float)atan2f(device.vScreenSize*0.5f, device.eyeToScreenDistance);
|
||||
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);
|
||||
|
||||
// Compute camera projection matrices
|
||||
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;
|
||||
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
|
||||
|
|
@ -2787,8 +2810,9 @@ void SetConfigFlags(unsigned int flags)
|
|||
void TakeScreenshot(const char *fileName)
|
||||
{
|
||||
#if defined(SUPPORT_MODULE_RTEXTURES)
|
||||
unsigned char *imgData = rlReadScreenPixels(CORE.Window.render.width, CORE.Window.render.height);
|
||||
Image image = { imgData, CORE.Window.render.width, CORE.Window.render.height, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
|
||||
Vector2 scale = GetWindowScaleDPI();
|
||||
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 };
|
||||
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)
|
||||
const char *GetFileNameWithoutExt(const char *filePath)
|
||||
{
|
||||
#define MAX_FILENAMEWITHOUTEXT_LENGTH 128
|
||||
#define MAX_FILENAMEWITHOUTEXT_LENGTH 256
|
||||
|
||||
static char fileName[MAX_FILENAMEWITHOUTEXT_LENGTH] = { 0 };
|
||||
memset(fileName, 0, MAX_FILENAMEWITHOUTEXT_LENGTH);
|
||||
|
|
@ -3222,8 +3246,8 @@ long GetFileModTime(const char *fileName)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Compress data (DEFLATE algorythm)
|
||||
unsigned char *CompressData(const unsigned char *data, int dataLength, int *compDataLength)
|
||||
// Compress data (DEFLATE algorithm)
|
||||
unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize)
|
||||
{
|
||||
#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)
|
||||
// Compress data and generate a valid DEFLATE stream
|
||||
struct sdefl sdefl = { 0 };
|
||||
int bounds = sdefl_bound(dataLength);
|
||||
int bounds = sdefl_bound(dataSize);
|
||||
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
|
||||
|
||||
return compData;
|
||||
}
|
||||
|
||||
// Decompress data (DEFLATE algorythm)
|
||||
unsigned char *DecompressData(const unsigned char *compData, int compDataLength, int *dataLength)
|
||||
// Decompress data (DEFLATE algorithm)
|
||||
unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize)
|
||||
{
|
||||
unsigned char *data = NULL;
|
||||
|
||||
#if defined(SUPPORT_COMPRESSION_API)
|
||||
// Decompress data from a valid DEFLATE stream
|
||||
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);
|
||||
|
||||
if (temp != NULL) data = temp;
|
||||
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
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// 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[] = {
|
||||
'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 };
|
||||
|
||||
*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;
|
||||
|
||||
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 octetB = (i < dataLength)? (unsigned char)data[i++] : 0;
|
||||
unsigned int octetC = (i < dataLength)? (unsigned char)data[i++] : 0;
|
||||
unsigned int octetA = (i < dataSize)? (unsigned char)data[i++] : 0;
|
||||
unsigned int octetB = (i < dataSize)? (unsigned char)data[i++] : 0;
|
||||
unsigned int octetC = (i < dataSize)? (unsigned char)data[i++] : 0;
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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[] = {
|
||||
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
|
||||
int outLength = 0;
|
||||
int outSize = 0;
|
||||
for (int i = 0; data[4*i] != 0; i++)
|
||||
{
|
||||
if (data[4*i + 3] == '=')
|
||||
{
|
||||
if (data[4*i + 2] == '=') outLength += 1;
|
||||
else outLength += 2;
|
||||
if (data[4*i + 2] == '=') outSize += 1;
|
||||
else outSize += 2;
|
||||
}
|
||||
else outLength += 3;
|
||||
else outSize += 3;
|
||||
}
|
||||
|
||||
// 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 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;
|
||||
}
|
||||
|
||||
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 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 b = base64decodeTable[(int)data[4*n + 1]];
|
||||
unsigned char c = base64decodeTable[(int)data[4*n + 2]];
|
||||
decodedData[outLength - 2] = (a << 2) | (b >> 4);
|
||||
decodedData[outLength - 1] = (b << 4) | (c >> 2);
|
||||
decodedData[outSize - 2] = (a << 2) | (b >> 4);
|
||||
decodedData[outSize - 1] = (b << 4) | (c >> 2);
|
||||
}
|
||||
|
||||
*outputLength = outLength;
|
||||
*outputSize = outSize;
|
||||
return decodedData;
|
||||
}
|
||||
|
||||
|
|
@ -3480,9 +3504,9 @@ void OpenURL(const char *url)
|
|||
#if defined(PLATFORM_DESKTOP)
|
||||
char *cmd = (char *)RL_CALLOC(strlen(url) + 10, sizeof(char));
|
||||
#if defined(_WIN32)
|
||||
sprintf(cmd, "explorer %s", url);
|
||||
sprintf(cmd, "explorer \"%s\"", url);
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__FreeBSD__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
sprintf(cmd, "xdg-open '%s'", url); // Alternatives: firefox, x-www-browser
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
|
|
@ -3494,6 +3518,29 @@ void OpenURL(const char *url)
|
|||
#endif
|
||||
#if defined(PLATFORM_WEB)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -4848,7 +4895,7 @@ void WaitTime(float ms)
|
|||
#if defined(_WIN32)
|
||||
Sleep((unsigned int)ms);
|
||||
#endif
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__EMSCRIPTEN__)
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__EMSCRIPTEN__)
|
||||
struct timespec req = { 0 };
|
||||
time_t sec = (int)(ms/1000.0f);
|
||||
ms -= (sec*1000);
|
||||
|
|
@ -4867,7 +4914,7 @@ void WaitTime(float ms)
|
|||
double currentTime = 0.0;
|
||||
|
||||
// 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
|
||||
}
|
||||
|
|
@ -4883,53 +4930,31 @@ void SwapScreenBuffer(void)
|
|||
eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
||||
|
||||
#if defined(PLATFORM_DRM)
|
||||
if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
||||
|
||||
struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface);
|
||||
if (!bo)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
||||
abort();
|
||||
}
|
||||
if (!bo) TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
||||
|
||||
uint32_t fb = 0;
|
||||
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);
|
||||
if (0 != result)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
||||
abort();
|
||||
}
|
||||
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);
|
||||
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
||||
|
||||
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]);
|
||||
if (0 != result)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
||||
abort();
|
||||
}
|
||||
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]);
|
||||
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
||||
|
||||
if (CORE.Window.prevFB)
|
||||
{
|
||||
result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
||||
if (0 != result)
|
||||
{
|
||||
TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
||||
abort();
|
||||
}
|
||||
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
||||
}
|
||||
|
||||
CORE.Window.prevFB = fb;
|
||||
|
||||
if (CORE.Window.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
||||
}
|
||||
if (CORE.Window.prevBO) gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
||||
|
||||
CORE.Window.prevBO = bo;
|
||||
|
||||
#endif // PLATFORM_DRM
|
||||
#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)
|
||||
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_RIGHT_TRIGGER_2] = (char)(CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_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.1f);
|
||||
|
||||
CORE.Input.Gamepad.axisCount = GLFW_GAMEPAD_AXIS_LAST + 1;
|
||||
}
|
||||
|
|
@ -5086,11 +5111,8 @@ void PollInputEvents(void)
|
|||
|
||||
CORE.Window.resizedLastFrame = false;
|
||||
|
||||
#if defined(SUPPORT_EVENTS_WAITING)
|
||||
glfwWaitEvents();
|
||||
#else
|
||||
glfwPollEvents(); // Register keyboard/mouse events (callbacks)... and window events!
|
||||
#endif
|
||||
if (CORE.Window.eventWaiting) glfwWaitEvents(); // Wait for in input events before continue (drawing is paused)
|
||||
else glfwPollEvents(); // Poll input events: keyboard/mouse/window events (callbacks)
|
||||
#endif // PLATFORM_DESKTOP
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
|
|
@ -5514,7 +5536,8 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
|||
gifRecording = true;
|
||||
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++;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// GLFW3 Srolling Callback, runs on mouse wheel
|
||||
// GLFW3 Scrolling Callback, runs on mouse wheel
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -6227,7 +6250,8 @@ static void InitEvdevInput(void)
|
|||
{
|
||||
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);
|
||||
ConfigureEvdevDevice(path); // Configure the device if appropriate
|
||||
|
|
@ -6387,7 +6411,7 @@ static void ConfigureEvdevDevice(char *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
|
||||
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
|
||||
|
|
@ -6699,7 +6723,7 @@ static void InitGamepad(void)
|
|||
{
|
||||
sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i);
|
||||
|
||||
if ((CORE.Input.Gamepad.streamId[i] = open(gamepadDev, O_RDONLY|O_NONBLOCK)) < 0)
|
||||
if ((CORE.Input.Gamepad.streamId[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0)
|
||||
{
|
||||
// NOTE: Only show message for first gamepad
|
||||
if (i == 0) TRACELOG(LOG_WARNING, "RPI: Failed to open Gamepad device, no gamepad available");
|
||||
|
|
@ -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,
|
||||
(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");
|
||||
continue;
|
||||
|
|
@ -6850,23 +6874,22 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((mode->hdisplay >= width) && (mode->vdisplay >= height) && (mode->vrefresh >= fps))
|
||||
if (nearestIndex < 0)
|
||||
{
|
||||
const int widthDiff = mode->hdisplay - width;
|
||||
const int heightDiff = mode->vdisplay - height;
|
||||
const int fpsDiff = mode->vrefresh - fps;
|
||||
nearestIndex = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (nearestIndex < 0)
|
||||
{
|
||||
nearestIndex = i;
|
||||
continue;
|
||||
}
|
||||
const int widthDiff = abs(mode->hdisplay - width);
|
||||
const int heightDiff = abs(mode->vdisplay - height);
|
||||
const int fpsDiff = abs(mode->vrefresh - fps);
|
||||
|
||||
const int nearestWidthDiff = CORE.Window.connector->modes[nearestIndex].hdisplay - width;
|
||||
const int nearestHeightDiff = CORE.Window.connector->modes[nearestIndex].vdisplay - height;
|
||||
const int nearestFpsDiff = CORE.Window.connector->modes[nearestIndex].vrefresh - fps;
|
||||
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;
|
||||
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)
|
||||
// NOTE: Loading happens over AutomationEvent *events
|
||||
// TODO: This system should probably be redesigned
|
||||
static void LoadAutomationEvents(const char *fileName)
|
||||
{
|
||||
//unsigned char fileId[4] = { 0 };
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@
|
|||
// NOTE: Below types are required for GESTURES_STANDALONE usage
|
||||
//----------------------------------------------------------------------------------
|
||||
// Boolean type
|
||||
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
||||
typedef enum bool { false, true } bool;
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#endif
|
||||
|
||||
#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
|
||||
} rlRenderBatch;
|
||||
|
||||
#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#include <stdbool.h>
|
||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
|
||||
// Boolean type
|
||||
typedef enum bool { false, true } bool;
|
||||
typedef enum bool { false = 0, true = !false } bool;
|
||||
#endif
|
||||
|
||||
#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 rlLoadExtensions(void *loader); // Load OpenGL extensions (loader function required)
|
||||
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 void rlSetFramebufferHeight(int height); // Set current framebuffer height
|
||||
RLAPI int rlGetFramebufferHeight(void); // Get default framebuffer height
|
||||
|
||||
RLAPI unsigned int rlGetTextureIdDefault(void); // Get default texture id
|
||||
|
|
@ -927,8 +929,8 @@ typedef struct rlglData {
|
|||
int glBlendDstFactor; // Blending destination factor
|
||||
int glBlendEquation; // Blending equation
|
||||
|
||||
int framebufferWidth; // Default framebuffer width
|
||||
int framebufferHeight; // Default framebuffer height
|
||||
int framebufferWidth; // Current framebuffer width
|
||||
int framebufferHeight; // Current framebuffer height
|
||||
|
||||
} State; // Renderer state
|
||||
struct {
|
||||
|
|
@ -1230,6 +1232,7 @@ void rlOrtho(double left, double right, double bottom, double top, double znear,
|
|||
#endif
|
||||
|
||||
// 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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
else TRACELOG(RL_LOG_WARNING, "GL: Anisotropic filtering not supported");
|
||||
|
|
@ -2219,6 +2222,22 @@ int rlGetVersion(void)
|
|||
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
|
||||
int rlGetFramebufferWidth(void)
|
||||
{
|
||||
|
|
@ -2601,6 +2620,9 @@ void rlDrawRenderBatch(rlRenderBatch *batch)
|
|||
|
||||
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
|
||||
|
|
@ -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 ((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
|
||||
|
||||
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 colorTint = WHITE;
|
||||
colorTint.r = (unsigned char)((((float)color.r/255.0)*((float)tint.r/255.0))*255.0f);
|
||||
colorTint.g = (unsigned char)((((float)color.g/255.0)*((float)tint.g/255.0))*255.0f);
|
||||
colorTint.b = (unsigned char)((((float)color.b/255.0)*((float)tint.b/255.0))*255.0f);
|
||||
colorTint.a = (unsigned char)((((float)color.a/255.0)*((float)tint.a/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.0f)*((float)tint.g/255.0f))*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.0f)*((float)tint.a/255.0f))*255.0f);
|
||||
|
||||
model.materials[model.meshMaterial[i]].maps[MATERIAL_MAP_DIFFUSE].color = colorTint;
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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
|
||||
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 };
|
||||
Vector3 edge1 = { 0 };
|
||||
|
|
@ -4662,7 +4643,6 @@ static Model LoadGLTF(const char *fileName)
|
|||
// Load our model data: meshes and materials
|
||||
model.meshCount = primitivesCount;
|
||||
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
|
||||
model.materialCount = (int)data->materials_count + 1;
|
||||
|
|
|
|||
20
src/rtext.c
20
src/rtext.c
|
|
@ -25,7 +25,7 @@
|
|||
*
|
||||
* DEPENDENCIES:
|
||||
* 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
|
||||
|
|
@ -229,7 +229,7 @@ extern void LoadFontDefault(void)
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
// 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.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...
|
||||
//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 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_node *nodes = (stbrp_node *)RL_MALLOC(glyphCount*sizeof(*nodes));
|
||||
|
|
@ -992,11 +992,11 @@ bool ExportFontAsCode(Font font, const char *fileName)
|
|||
// NOTE: Uses default font
|
||||
void DrawFPS(int posX, int posY)
|
||||
{
|
||||
Color color = LIME; // good fps
|
||||
Color color = LIME; // Good FPS
|
||||
int fps = GetFPS();
|
||||
|
||||
if (fps < 30 && fps >= 15) color = ORANGE; // warning FPS
|
||||
else if (fps < 15) color = RED; // bad FPS
|
||||
if ((fps < 30) && (fps >= 15)) color = ORANGE; // Warning FPS
|
||||
else if (fps < 15) color = RED; // Low FPS
|
||||
|
||||
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
|
||||
// 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)
|
||||
{
|
||||
// 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
|
||||
// WARNING: Allocated memory should be manually freed
|
||||
// WARNING: Allocated memory must be manually freed
|
||||
char *TextInsert(const char *text, const char *insert, int position)
|
||||
{
|
||||
int textLen = TextLength(text);
|
||||
|
|
@ -1616,7 +1616,7 @@ const char *TextToPascal(const char *text)
|
|||
|
||||
// Encode text codepoint into UTF-8 text
|
||||
// REQUIRES: memcpy()
|
||||
// WARNING: Allocated memory should be manually freed
|
||||
// WARNING: Allocated memory must be manually freed
|
||||
char *TextCodepointsToUTF8(const int *codepoints, int length)
|
||||
{
|
||||
// We allocate enough memory fo fit all possible codepoints
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
* DEPENDENCIES:
|
||||
* stb_image - Multiple image formats loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC)
|
||||
* 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
|
||||
|
|
@ -306,10 +306,9 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
|
|||
{
|
||||
Image image = { 0 };
|
||||
|
||||
#if defined(SUPPORT_FILEFORMAT_PNG)
|
||||
if ((strcmp(fileType, ".png") == 0)
|
||||
#else
|
||||
if ((false)
|
||||
#if defined(SUPPORT_FILEFORMAT_PNG)
|
||||
|| (strcmp(fileType, ".png") == 0)
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_BMP)
|
||||
|| (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 a = (unsigned char)(((float)pixels[index].a/255*cA)*255.0f);
|
||||
|
||||
pixels[y*image->width + x].r = r;
|
||||
pixels[y*image->width + x].g = g;
|
||||
pixels[y*image->width + x].b = b;
|
||||
pixels[y*image->width + x].a = a;
|
||||
pixels[index].r = r;
|
||||
pixels[index].g = g;
|
||||
pixels[index].b = b;
|
||||
pixels[index].a = a;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1959,25 +1958,25 @@ void ImageColorContrast(Image *image, float contrast)
|
|||
for (int x = 0; x < image->width; x++)
|
||||
{
|
||||
float pR = (float)pixels[y*image->width + x].r/255.0f;
|
||||
pR -= 0.5;
|
||||
pR -= 0.5f;
|
||||
pR *= contrast;
|
||||
pR += 0.5;
|
||||
pR += 0.5f;
|
||||
pR *= 255;
|
||||
if (pR < 0) pR = 0;
|
||||
if (pR > 255) pR = 255;
|
||||
|
||||
float pG = (float)pixels[y*image->width + x].g/255.0f;
|
||||
pG -= 0.5;
|
||||
pG -= 0.5f;
|
||||
pG *= contrast;
|
||||
pG += 0.5;
|
||||
pG += 0.5f;
|
||||
pG *= 255;
|
||||
if (pG < 0) pG = 0;
|
||||
if (pG > 255) pG = 255;
|
||||
|
||||
float pB = (float)pixels[y*image->width + x].b/255.0f;
|
||||
pB -= 0.5;
|
||||
pB -= 0.5f;
|
||||
pB *= contrast;
|
||||
pB += 0.5;
|
||||
pB += 0.5f;
|
||||
pB *= 255;
|
||||
if (pB < 0) pB = 0;
|
||||
if (pB > 255) pB = 255;
|
||||
|
|
@ -2412,7 +2411,20 @@ Color GetImageColor(Image image, int x, int y)
|
|||
// Clear image background with given 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
|
||||
|
|
@ -2686,13 +2698,21 @@ void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color)
|
|||
int ey = sy + (int)rec.height;
|
||||
|
||||
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 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.y = (nPatchInfo.source.y + nPatchInfo.source.height)/height;
|
||||
|
||||
rlCheckRenderBatchLimit(9 * 3 * 2); // Maxium number of verts that could happen
|
||||
|
||||
rlSetTexture(texture.id);
|
||||
|
||||
rlPushMatrix();
|
||||
|
|
|
|||
46
src/utils.c
46
src/utils.c
|
|
@ -148,6 +148,7 @@ void TraceLog(int logType, const char *text, ...)
|
|||
strcat(buffer, text);
|
||||
strcat(buffer, "\n");
|
||||
vprintf(buffer, args);
|
||||
fflush(stdout);
|
||||
#endif
|
||||
|
||||
va_end(args);
|
||||
|
|
@ -268,6 +269,51 @@ bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite)
|
|||
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
|
||||
// NOTE: text chars array should be freed manually
|
||||
char *LoadFileText(const char *fileName)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user