mirror of
https://github.com/raysan5/raylib.git
synced 2026-04-10 01:09:10 -04:00
Compare commits
22 Commits
12140cd444
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| fbcc8cdb55 | |||
| ca6f188233 | |||
| 8e54b19d9f | |||
| e24b01bb28 | |||
| 68d519910a | |||
| 53915d77e6 | |||
| b202421e08 | |||
| 05a14456ae | |||
| c5fc771622 | |||
| d3c6f426b4 | |||
| c4bd4faab5 | |||
| 4a6ceb9c76 | |||
| 6ef0044381 | |||
| 1122add3ee | |||
| 92f82b4add | |||
| cdff3d7bea | |||
| 138ef838d9 | |||
| 6ff51d3a2a | |||
| ea6292e27a | |||
| bb7b8d70e9 | |||
| f36533cbd8 | |||
| 5c2dee0862 |
@ -4,7 +4,7 @@ changelog
|
||||
Current Release: raylib 5.5 (18 November 2024)
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
Release: raylib 6.0 (?? March 2026)
|
||||
Release: raylib 6.0 (23 April 2026)
|
||||
-------------------------------------------------------------------------
|
||||
KEY CHANGES:
|
||||
- New Software Renderer backend [rlsw]
|
||||
@ -221,6 +221,7 @@ Detailed changes:
|
||||
[rlsw] REVIEWED: C++ support (#5291) by @alexgb0
|
||||
[rshapes] ADDED: `DrawLineDashed()` (#5222) by @luis605
|
||||
[rshapes] ADDED: `DrawEllipseV()` and `DrawEllipseLinesV()` (#4963) by @meowstr
|
||||
[rshapes] REDESIGNED: `DrawCircleGradient()` to use Vector2 as center parameter by @raysan5 -WARNING-
|
||||
[rshapes] REVIEWED: `DrawLine()`, fix pixel offset issue on drawing (#4666) by @Bigfoot71
|
||||
[rshapes] REVIEWED: `DrawRectangleGradientEx()`, incorrect parameter names (#4980) by @vincent
|
||||
[rshapes] REVIEWED: `DrawRectangleLines`, fix pixel offset issue (#4669) by @Bigfoot71
|
||||
@ -285,6 +286,7 @@ Detailed changes:
|
||||
[rtext] REVIEWED: `TextToFloat()`, remove removed inaccurate comment (#4596) by @hexmaster111
|
||||
[rtext] REDESIGNED: `LoadFontData()`, added input parameter by @raysan5 -WARNING-
|
||||
[rmodels] ADDED: Support CPU animation in OpenGL 1.1 (#4925) by @JeffM2501
|
||||
[rmodels] REMOVED: `DrawModelPoints()` and `DrawModelPointsEx()`, moved to an example (#5697) by @maiconpintoabreu -WARNING-
|
||||
[rmodels] RENAMED: Skinning shader variables (new default naming) by @raysan5
|
||||
[rmodels] REVIEWED: glTF animation framerate calculation (#4472, #5445) by @TheLazyIndianTechie
|
||||
[rmodels] REVIEWED: Assign meshes without bone weights to the bone they are attached to so they animate by @Jeffm2501
|
||||
@ -311,6 +313,7 @@ Detailed changes:
|
||||
[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, properly load 1 frame animations (#5561) by @arlez80
|
||||
[rmodels] REVIEWED: `LoadModelAnimationsGLTF()`, anim correctly inherits world transform (#5206) by @ArmanOmmid
|
||||
[rmodels] REVIEWED: `UploadMesh()`, improve default normal and tangent values (#4763) by @Bigfoot71
|
||||
[rmodels] REVIEWED: `UplaodMesh()`, fix for devices without VAO support (#5692) by @psxdev
|
||||
[rmodels] REVIEWED: `GenMeshTangents()`, improvements (#4937) by @Bigfoot71
|
||||
[rmodels] REVIEWED: `UpdateModelAnimation()` optimization (#5244) by @Arrangemonk
|
||||
[rmodels] REVIEWED: `UpdateModelAnimationBones()`, break on first mesh found and formating by @raysan5
|
||||
@ -322,6 +325,7 @@ Detailed changes:
|
||||
[rmodels] REVIEWED: `DrawMeshInstanced()`, breaking if instanceTransform was unused (#5469) by @al13n321
|
||||
[rmodels] REVIEWED: `DrawSphereEx()`, normals support (#4926) by @karl-zylinski
|
||||
[rmodels] REVIEWED: `ExportMesh()`, improve OBJ vertex data precision and lower memory usage (#4496) by @mikeemm
|
||||
[rmodels] REVIEWED: `CheckCollisionSpheres()`, simplified using `Vector3DistanceSqr()` (#5695) by @Bigfoot71
|
||||
[raudio] REVIEWED: Fix a glitch at the end of a sound (#5578) by @mackron
|
||||
[raudio] REVIEWED: Improvements to device configuration (#5577) by @mackron
|
||||
[raudio] REVIEWED: Initialize sound alias properties as if it was a new sound (#5123) by @JeffM2501
|
||||
|
||||
85
HISTORY.md
85
HISTORY.md
@ -526,26 +526,79 @@ Last but not least, I want to thank **raylib sponsors and all the raylib communi
|
||||
notes on raylib 6.0
|
||||
-------------------
|
||||
|
||||
A new raylib release is finally ready, after almost 1.5 years since last release. This is the biggest release ever with many improvements to the library, thanks to the support of many amazing contributors and also thanks to the financial support of NLnet/NGI0 funds.
|
||||
A new `raylib` release is finally ready and, again, this is the **biggest `raylib` release ever**! Thanks to the support of many amazing contributors this release comes packed with many new features and improvements, also thanks to the financial support of [NLnet](https://nlnet.nl/) and the [NGI Zero Commond Fund](https://nlnet.nl/NGI0/) that allow me to work on this project mostly fulltime for the past few months.
|
||||
|
||||
Some astonishing numbers for this release:
|
||||
|
||||
- **+320** closed issues (for a TOTAL of **+2130**!)
|
||||
- **+1800** commits since previous RELEASE (for a TOTAL of **+9600**!)
|
||||
- **18** functions ADDED to raylib API (for a TOTAL of **599**!)
|
||||
- **+50** new examples to learn from (for a TOTAL of **212**!)
|
||||
- **+200** new contributors (for a TOTAL of **+840**!)
|
||||
- **+320** closed issues (for a TOTAL of **+2140**!)
|
||||
- **+1950** commits since previous RELEASE (for a TOTAL of **+9700**!)
|
||||
- **+20** new functions ADDED to raylib API (for a TOTAL of **600**!)
|
||||
- **+50** new examples to learn from (for a TOTAL of **+210**!)
|
||||
- **+210** new contributors (for a TOTAL of **+850**!)
|
||||
|
||||
Highlights for `raylib 6.0`:
|
||||
|
||||
- New Software Renderer backend [rlsw]
|
||||
- New rcore platform backend: Memory (memory buffer)
|
||||
- New rcore platform backend: Win32 (experimental)
|
||||
- New rcore platform backend: Emscripten (experimental)
|
||||
- Redesigned Skeletal Animation System
|
||||
- Redesigned fullscreen modes and high-dpi content scaling
|
||||
- Redesigned Build Config System [config.h]
|
||||
- New File System API
|
||||
- New Text Management API
|
||||
- New tool: [rexm] raylib examples manager
|
||||
- **`NEW` Software Renderer - [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h)**: The biggest addition of this new release. A new software renderer backend, that allows raylib to run purely on CPU, with no neeed for a GPU. It finally closes the circle of my search for a portable self-contained, with **no-external-dependencies**, graphics library, able to run on any device providing some CPU-power and some RAM memory. It has been possible thanks to the amazing work of **Le Juez Victor** ([@Bigfoot71](https://github.com/Bigfoot71)), who created [`rlsw`](https://github.com/raysan5/raylib/blob/master/src/external/rlsw.h), a single-file header-only library implementing OpenGL 1.1+ specification, tailored to fit into raylib [`rlgl`](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) OpenGL wrapper, and allowing to run raylib seamlessly over CPU with **no code changes required on user side**. As expected, software rendering is slower than hardware-accelerated rendering but it is still fast enough to run basic application at 30-60 fps. Actually, it already proved it usefulness on a new [raylib port for ESP32](https://components.espressif.com/components/georgik/raylib/versions/6.0.0/readme) microcontroller by Espressif, useful for industrial applications, and opens the door to the upcoming RISC-V powered devices that start arriving to the marked, and many times come with no GPU. Along the new software renderer, some of the existing platform backends have been adapted to support it (SDL, RGFW, DRM) and also **new platforms backends have been created** to accomodate it (Win32, Emscripten), incluing a new `PLATFORM_MEMORY`, that allows direct rendering to a memory framebuffer.
|
||||
|
||||
- **`NEW` Platform backend: Memory - [`rcore_memory`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_memory.c)**: This new platform has been added along the **software renderer** backend, allowing 2d and 3d rendering over a **platform-agnostic memory framebuffer**, it can run headless and output frames can be directly exported to images. This new backend could also be useful for graphics rendering on servers or process images directly using the memory buffer.
|
||||
|
||||
- **`NEW` Platform backend: Win32 - [`rcore_desktop_win32`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_desktop_win32.c)**: A new **Windows platform backend** and the first step towards a potential replacement/alternative to the platform libraries currently used by raylib (GLFW/SDL/RGFW). This backend follows same API template structure than the other raylib backends, but directly implementing Win32 API calls. It allows initializing OpenGL GPU-accelerated windows and also GDI based windows, useful for the software renderer backend. This new backend approach, following a common template-structure and separating the platform logic by specific OS/Windowing system, will simplify code, improve maintenance, readability and portability for raylib, setting some bases for the future. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||
|
||||
- **`NEW` Platform backend: Emscripten - [`rcore_web_emscripten`](https://github.com/raysan5/raylib/blob/master/src/platforms/rcore_web_emscripten.c)**: In the same line as Win32 backend, this new web backend moves away from `libglfw.js` and **directly implements Emscripten/JS functionality**, with **no other dependencies**, adding support for the new software renderer to draw directly on a **non-accelerated 2d canvas** but also supporting a WebGL-hardware-accelerated canvas when required. *NOTE: This backend is new and it could require further testing, use it as an experimental backend for now.*
|
||||
|
||||
- **`REDESIGNED` Fullscreen modes and High-DPI content scaling**: After many years and many related issues, the full-screen and high-dpi content scaling support has been **completely redesigned** from scratch. New design prioritizes **borderless fullscreen modes** and automatically detects current monitor content scaling configuration to scale window and framebuffer accordingly when required. Still, High-DPI support must be requested by user if desired enabling `FLAG_WINDOW_HIGHDPI` on window creation. This new system has been carefully tested on Windows, Linux (X11, Wayland), macOS with multiple monitors and multiple resolutions, including 4K monitors.
|
||||
|
||||
- **`REDESIGNED` Skeletal Animation System**: A new animation system for 3d models has been created to support animation blending, between single frames but also between differents frames on different animations, to allow easy **timed transitions** between animations. This redesign implied reviewing several raylib structures to better accomodate animation data: `Model`, `ModelSkeleton`, `ModelAnimation`, but the API was simplified and support for GPU-skinning was improved with multiple optimizations.
|
||||
|
||||
- **`REDESIGNED` Build Config System - [`config.h`](https://github.com/raysan5/raylib/blob/master/src/config.h)**: raylib allows lot of customization for specific needs (i.e. disabling modules not needed for specific applications like rmodels or raudio) but previous implementation did not allow easely disabling some features from **custom build systems**. New design not only allows disabling features with simple `-DSUPPORT_FILEFORMAT_OBJ=0` on building command-line but also the full system has been reviewed, removing useless flags and exposing new ones.
|
||||
|
||||
- **`NEW` File System API**: Along the years, multiple filesystem functions have been added to raylib API as required but it felt somewhat inconsistent with some pieces missing. In this new release, the full filesystem API has beeen reviewed and reorganized, compiling all the functionality single module: [rcore](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L1126), consequently `utils` module has been removed and build system has been simplified even more; **only 6-7 modules (.c) need to be compiled containing the full raylib library**. This new filesystem API will allow raylib to be used on the creation of custom build systems, as already demostrated with the new `rexm` tool for examples management. At the moment raylib includes **+40 file system management functions**, here a list with the new functions added:
|
||||
```c
|
||||
int FileRename(const char *fileName, const char *fileRename); // Rename file (if exists)
|
||||
int FileRemove(const char *fileName); // Remove file (if exists)
|
||||
int FileCopy(const char *srcPath, const char *dstPath); // Copy file from one path to another, dstPath created if it doesn't exist
|
||||
int FileMove(const char *srcPath, const char *dstPath); // Move file from one directory to another, dstPath created if it doesn't exist
|
||||
int FileTextReplace(const char *fileName, const char *search, const char *replacement); // Replace text in an existing file
|
||||
int FileTextFindIndex(const char *fileName, const char *search); // Find text in existing file
|
||||
```
|
||||
|
||||
- **`NEW` Text Management API**: Along with the new file system functionality, a new set of text management functions has been added, also very useful for text procesing and also used in custom build systems creation using raylib. At the moment raylib includes **+30 text management functions**, here a list with the new functions added:
|
||||
```c
|
||||
char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
|
||||
void UnloadTextLines(char **text, int lineCount); // Unload text lines
|
||||
const char *TextRemoveSpaces(const char *text); // Remove text spaces, concat words
|
||||
char *GetTextBetween(const char *text, const char *begin, const char *end); // Get text between two strings
|
||||
char *TextReplace(const char *text, const char *search, const char *replacement); // Replace text string with new string
|
||||
char *TextReplaceAlloc(const char *text, const char *search, const char *replacement); // Replace text string with new string, memory must be MemFree()
|
||||
char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings
|
||||
char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings, memory must be MemFree()
|
||||
char *TextInsertAlloc(const char *text, const char *insert, int position); // Insert text in a defined byte position, memory must be MemFree()
|
||||
```
|
||||
|
||||
- **`NEW` tool: raylib examples manager - [rexm](https://github.com/raysan5/raylib/tree/master/tools/rexm)**: raylib examples collection is huge, with **more than 200 examples** it was quite difficult to manage: adding, removing, renaming examples was a very costly process involving many files to be modified (including build systems), also the examples did not follow a common header convention neither a structure conventions. For that reason, a new support tool has been created: **rexm**, a raylib examples manager that allows to easely add/remove/rename examples, automatically fix inconsistencies and even **building and automated testing** on multiple platforms.
|
||||
```
|
||||
USAGE:
|
||||
> rexm <command> <example_name> [<example_rename>]
|
||||
|
||||
COMMANDS:
|
||||
create <new_example_name> : Creates an empty example, from internal template
|
||||
add <example_name> : Add existing example to collection
|
||||
rename <old_examples_name> <new_example_name> : Rename an existing example
|
||||
remove <example_name> : Remove an existing example from collection
|
||||
build <example_name> : Build example for Desktop and Web platforms
|
||||
test <example_name> : Build and Test example for Desktop and Web platforms
|
||||
validate : Validate examples collection, generates report
|
||||
update : Validate and update examples collection, generates report
|
||||
```
|
||||
|
||||
- **`NEW` +50 new examples**: Thanks to `rexm` and the simplification on examples management, this new raylib release includes +50 new examples to leearn from, most of them contributed by community.
|
||||
|
||||
Make sure to check raylib [CHANGELOG](https://github.com/raysan5/raylib/blob/master/CHANGELOG) for a detailed list of changes!
|
||||
|
||||
I want to **thank all the contributors (+850!**) that along the years have **greatly improved raylib** and pushed it further and better day after day. And **many thanks to raylib community and all raylib users** for supporting the library along those many years.
|
||||
|
||||
Finally, I want to thank [puffer.ai](https://puffer.ai/) and [comma.ai](https://comma.ai/) for **supporting and sponsoring the project** as platinum sponsors, along many others individuals that have been sponsoring raylib along the years. Thanks to all of you for allowing me to keep working on this library!
|
||||
|
||||
**After +12 years of development, `raylib 6.0` is today one of the bests libraries to enjoy games/tools/graphic programming!**
|
||||
|
||||
**Enjoy graphics programming with raylib!** :)
|
||||
|
||||
@ -202,8 +202,10 @@ fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.
|
||||
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
|
||||
}
|
||||
|
||||
raylib.root_module.linkSystemLibrary("EGL", .{});
|
||||
raylib.root_module.linkSystemLibrary("gbm", .{});
|
||||
if (options.opengl_version != .gl_soft) {
|
||||
raylib.root_module.linkSystemLibrary("EGL", .{});
|
||||
raylib.root_module.linkSystemLibrary("gbm", .{});
|
||||
}
|
||||
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
|
||||
|
||||
raylib.root_module.addCMacro("PLATFORM_DRM", "");
|
||||
@ -416,6 +418,7 @@ pub const Options = struct {
|
||||
|
||||
pub const OpenglVersion = enum {
|
||||
auto,
|
||||
gl_soft,
|
||||
gl_1_1,
|
||||
gl_2_1,
|
||||
gl_3_3,
|
||||
@ -426,6 +429,7 @@ pub const OpenglVersion = enum {
|
||||
pub fn toCMacroStr(self: @This()) []const u8 {
|
||||
switch (self) {
|
||||
.auto => @panic("OpenglVersion.auto cannot be turned into a C macro string"),
|
||||
.gl_soft => return "GRAPHICS_API_OPENGL_SOFTWARE",
|
||||
.gl_1_1 => return "GRAPHICS_API_OPENGL_11",
|
||||
.gl_2_1 => return "GRAPHICS_API_OPENGL_21",
|
||||
.gl_3_3 => return "GRAPHICS_API_OPENGL_33",
|
||||
|
||||
@ -96,21 +96,30 @@ elseif (${PLATFORM} STREQUAL "Android")
|
||||
|
||||
elseif ("${PLATFORM}" STREQUAL "DRM")
|
||||
set(PLATFORM_CPP "PLATFORM_DRM")
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
|
||||
add_definitions(-D_DEFAULT_SOURCE)
|
||||
add_definitions(-DEGL_NO_X11)
|
||||
add_definitions(-DPLATFORM_DRM)
|
||||
|
||||
find_library(GLESV2 GLESv2)
|
||||
find_library(EGL EGL)
|
||||
find_library(DRM drm)
|
||||
find_library(GBM gbm)
|
||||
|
||||
if (NOT CMAKE_CROSSCOMPILING OR NOT CMAKE_SYSROOT)
|
||||
include_directories(/usr/include/libdrm)
|
||||
endif ()
|
||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
||||
|
||||
if ("${OPENGL_VERSION}" STREQUAL "Software")
|
||||
# software rendering does not require EGL/GBM.
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_SOFTWARE")
|
||||
set(LIBS_PRIVATE ${DRM} atomic pthread dl)
|
||||
else ()
|
||||
set(GRAPHICS "GRAPHICS_API_OPENGL_ES2")
|
||||
add_definitions(-DEGL_NO_X11)
|
||||
|
||||
find_library(GLESV2 GLESv2)
|
||||
find_library(EGL EGL)
|
||||
find_library(GBM gbm)
|
||||
|
||||
set(LIBS_PRIVATE ${GLESV2} ${EGL} ${DRM} ${GBM} atomic pthread dl)
|
||||
endif ()
|
||||
set(LIBS_PUBLIC m)
|
||||
|
||||
elseif ("${PLATFORM}" STREQUAL "SDL")
|
||||
|
||||
238
examples/audio/audio_amp_envelope.c
Normal file
238
examples/audio/audio_amp_envelope.c
Normal file
@ -0,0 +1,238 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [audio] example - amp envelope
|
||||
*
|
||||
* Example complexity rating: [★☆☆☆] 1/4
|
||||
*
|
||||
* Example originally created with raylib 6.0, last time updated with raylib 6.0
|
||||
*
|
||||
* Example contributed by Arbinda Rizki Muhammad (@arbipink) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2026 Arbinda Rizki Muhammad (@arbipink)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define RAYGUI_IMPLEMENTATION
|
||||
#include "raygui.h"
|
||||
|
||||
#include <math.h> // Required for: sinf()
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
#define SAMPLE_RATE 44100
|
||||
|
||||
// Wave state
|
||||
typedef enum {
|
||||
IDLE,
|
||||
ATTACK,
|
||||
DECAY,
|
||||
SUSTAIN,
|
||||
RELEASE
|
||||
} ADSRState;
|
||||
|
||||
// Grouping all ADSR parameters and state into a struct
|
||||
typedef struct {
|
||||
float attackTime;
|
||||
float decayTime;
|
||||
float sustainLevel;
|
||||
float releaseTime;
|
||||
float currentValue;
|
||||
ADSRState state;
|
||||
} Envelope;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//------------------------------------------------------------------------------------
|
||||
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime);
|
||||
static void UpdateEnvelope(Envelope *env);
|
||||
static void DrawADSRGraph(Envelope *env, Rectangle bounds);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const int screenWidth = 800;
|
||||
const int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [audio] example - amp envelope");
|
||||
|
||||
InitAudioDevice();
|
||||
|
||||
// Set the number of samples the stream will keep in memory at a time to BUFFER_SIZE
|
||||
SetAudioStreamBufferSizeDefault(BUFFER_SIZE);
|
||||
float buffer[BUFFER_SIZE] = { 0 };
|
||||
|
||||
// Init raw audio stream (sample rate: 44100, sample size: 32bit-float, channels: 1-mono)
|
||||
AudioStream stream = LoadAudioStream(SAMPLE_RATE, 32, 1);
|
||||
|
||||
// Init Phase
|
||||
float audioTime = 0.0f;
|
||||
|
||||
// Initialize the struct
|
||||
Envelope env = {
|
||||
.attackTime = 1.0f,
|
||||
.decayTime = 1.0f,
|
||||
.sustainLevel = 0.5f,
|
||||
.releaseTime = 1.0f,
|
||||
.currentValue = 0.0f,
|
||||
.state = IDLE
|
||||
};
|
||||
|
||||
SetTargetFPS(60);
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_SPACE)) env.state = ATTACK;
|
||||
|
||||
if (IsKeyReleased(KEY_SPACE) && (env.state != IDLE)) env.state = RELEASE;
|
||||
|
||||
if (IsAudioStreamProcessed(stream))
|
||||
{
|
||||
if ((env.state != IDLE) || (env.currentValue > 0.0f))
|
||||
{
|
||||
for (int i = 0; i < BUFFER_SIZE; i++)
|
||||
{
|
||||
UpdateEnvelope(&env);
|
||||
FillAudioBuffer(i, buffer, env.currentValue, &audioTime);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear buffer if silent to avoid looping noise
|
||||
for (int i = 0; i < BUFFER_SIZE; i++) buffer[i] = 0;
|
||||
audioTime = 0.0f;
|
||||
}
|
||||
|
||||
UpdateAudioStream(stream, buffer, BUFFER_SIZE);
|
||||
}
|
||||
|
||||
if (!IsAudioStreamPlaying(stream)) PlayAudioStream(stream);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
GuiSliderBar((Rectangle){ 100, 60, 400, 30 }, "Attack (s)", TextFormat("%2.2fs", env.attackTime), &env.attackTime, 0.1f, 3.0f);
|
||||
GuiSliderBar((Rectangle){ 100, 100, 400, 30 }, "Decay (s)", TextFormat("%2.2fs", env.decayTime), &env.decayTime, 0.1f, 3.0f);
|
||||
GuiSliderBar((Rectangle){ 100, 140, 400, 30 }, "Sustain", TextFormat("%2.2f", env.sustainLevel), &env.sustainLevel, 0.0f, 1.0f);
|
||||
GuiSliderBar((Rectangle){ 100, 180, 400, 30 }, "Release (s)", TextFormat("%2.2fs", env.releaseTime), &env.releaseTime, 0.1f, 3.0f);
|
||||
|
||||
DrawADSRGraph(&env, (Rectangle){ 100, 250, 400, 100 });
|
||||
|
||||
DrawCircleV((Vector2){ 520, 350 - (env.currentValue * 100) }, 5, MAROON);
|
||||
DrawText(TextFormat("Current Gain: %2.2f", env.currentValue), 535, 345 - (env.currentValue * 100), 10, MAROON);
|
||||
|
||||
DrawText("Press SPACE to PLAY the sound!", 200, 400, 20, LIGHTGRAY);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadAudioStream(stream);
|
||||
CloseAudioDevice();
|
||||
|
||||
CloseWindow();
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//------------------------------------------------------------------------------------
|
||||
static void FillAudioBuffer(int i, float *buffer, float envelopeValue, float *audioTime)
|
||||
{
|
||||
int frequency = 440;
|
||||
buffer[i] = envelopeValue*sinf(2.0f*PI*frequency*(*audioTime));
|
||||
*audioTime += (1.0f/SAMPLE_RATE);
|
||||
}
|
||||
|
||||
static void UpdateEnvelope(Envelope *env)
|
||||
{
|
||||
// Calculate the time delta for ONE sample (1/44100)
|
||||
float sampleTime = 1.0f/SAMPLE_RATE;
|
||||
|
||||
switch(env->state)
|
||||
{
|
||||
case ATTACK:
|
||||
{
|
||||
env->currentValue += (1.0f/env->attackTime)*sampleTime;
|
||||
if (env->currentValue >= 1.0f)
|
||||
{
|
||||
env->currentValue = 1.0f;
|
||||
env->state = DECAY;
|
||||
}
|
||||
|
||||
} break;
|
||||
case DECAY:
|
||||
{
|
||||
env->currentValue -= ((1.0f - env->sustainLevel)/env->decayTime)*sampleTime;
|
||||
if (env->currentValue <= env->sustainLevel)
|
||||
{
|
||||
env->currentValue = env->sustainLevel;
|
||||
env->state = SUSTAIN;
|
||||
}
|
||||
|
||||
} break;
|
||||
case SUSTAIN:
|
||||
{
|
||||
env->currentValue = env->sustainLevel;
|
||||
|
||||
} break;
|
||||
case RELEASE:
|
||||
{
|
||||
env->currentValue -= (env->sustainLevel/env->releaseTime)*sampleTime;
|
||||
if (env->currentValue <= 0.001f) // Use a small threshold to avoid infinite tail
|
||||
{
|
||||
env->currentValue = 0.0f;
|
||||
env->state = IDLE;
|
||||
}
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawADSRGraph(Envelope *env, Rectangle bounds)
|
||||
{
|
||||
DrawRectangleRec(bounds, Fade(LIGHTGRAY, 0.3f));
|
||||
DrawRectangleLinesEx(bounds, 1, GRAY);
|
||||
|
||||
// Fixed visual width for sustain stage since it's an amplitude not a time value
|
||||
float sustainWidth = 1.0f;
|
||||
|
||||
// Total time to visualize (sum of A, D, R + a padding for Sustain)
|
||||
float totalTime = env->attackTime + env->decayTime + sustainWidth + env->releaseTime;
|
||||
|
||||
float scaleX = bounds.width/totalTime;
|
||||
float scaleY = bounds.height;
|
||||
|
||||
Vector2 start = { bounds.x, bounds.y + bounds.height };
|
||||
Vector2 peak = { start.x + (env->attackTime*scaleX), bounds.y };
|
||||
Vector2 sustain = { peak.x + (env->decayTime*scaleX), bounds.y + (1.0f - env->sustainLevel)*scaleY };
|
||||
Vector2 rel = { sustain.x + (sustainWidth*scaleX), sustain.y };
|
||||
Vector2 end = { rel.x + (env->releaseTime*scaleX), bounds.y + bounds.height };
|
||||
|
||||
DrawLineV(start, peak, SKYBLUE);
|
||||
DrawLineV(peak, sustain, BLUE);
|
||||
DrawLineV(sustain, rel, DARKBLUE);
|
||||
DrawLineV(rel, end, ORANGE);
|
||||
|
||||
DrawText("ADSR Visualizer", bounds.x, bounds.y - 20, 10, DARKGRAY);
|
||||
}
|
||||
BIN
examples/audio/audio_amp_envelope.png
Normal file
BIN
examples/audio/audio_amp_envelope.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
6051
examples/audio/raygui.h
Normal file
6051
examples/audio/raygui.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,7 @@ int main(void)
|
||||
DrawText("USING DEFAULT SHADER", 20, 40, 10, RED);
|
||||
|
||||
DrawCircle(80, 120, 35, DARKBLUE);
|
||||
DrawCircleGradient(80, 220, 60, GREEN, SKYBLUE);
|
||||
DrawCircleGradient((Vector2){ 80.0f, 220.0f }, 60, GREEN, SKYBLUE);
|
||||
DrawCircleLines(80, 340, 80, DARKBLUE);
|
||||
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ int main(void)
|
||||
|
||||
// Circle shapes and lines
|
||||
DrawCircle(screenWidth/5, 120, 35, DARKBLUE);
|
||||
DrawCircleGradient(screenWidth/5, 220, 60, GREEN, SKYBLUE);
|
||||
DrawCircleGradient((Vector2){ screenWidth/5.0f, 220.0f }, 60, GREEN, SKYBLUE);
|
||||
DrawCircleLines(screenWidth/5, 340, 80, DARKBLUE);
|
||||
DrawEllipse(screenWidth/5, 120, 25, 20, YELLOW);
|
||||
DrawEllipseLines(screenWidth/5, 120, 30, 25, YELLOW);
|
||||
|
||||
@ -341,7 +341,7 @@ static void DrawLightMask(int slot)
|
||||
rlSetBlendMode(BLEND_CUSTOM);
|
||||
|
||||
// If we are valid, then draw the light radius to the alpha mask
|
||||
if (lights[slot].valid) DrawCircleGradient((int)lights[slot].position.x, (int)lights[slot].position.y, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE);
|
||||
if (lights[slot].valid) DrawCircleGradient(lights[slot].position, lights[slot].outerRadius, ColorAlpha(WHITE, 0), WHITE);
|
||||
|
||||
rlDrawRenderBatchActive();
|
||||
|
||||
|
||||
10
src/external/rlsw.h
vendored
10
src/external/rlsw.h
vendored
@ -2357,7 +2357,8 @@ static inline bool sw_texture_alloc(sw_texture_t *texture, const void *data, int
|
||||
|
||||
sw_pixel_read_color8_f readColor8 = NULL;
|
||||
sw_pixel_read_color_f readColor = NULL;
|
||||
if (!isDepth) {
|
||||
if (!isDepth)
|
||||
{
|
||||
readColor8 = sw_pixel_get_read_color8_func(format);
|
||||
readColor = sw_pixel_get_read_color_func(format);
|
||||
}
|
||||
@ -2803,7 +2804,8 @@ static const sw_blend_f SW_BLEND_TABLE[SW_BLEND_FACTOR_COUNT][SW_BLEND_FACTOR_CO
|
||||
// Maps a GL blend factor enum to its compact table index
|
||||
static inline int sw_blend_factor_index(SWfactor f)
|
||||
{
|
||||
switch (f) {
|
||||
switch (f)
|
||||
{
|
||||
case SW_ZERO: return 0;
|
||||
case SW_ONE: return 1;
|
||||
case SW_SRC_COLOR: return 2;
|
||||
@ -2821,7 +2823,8 @@ static inline int sw_blend_factor_index(SWfactor f)
|
||||
|
||||
static bool sw_blend_factor_needs_alpha(SWfactor f)
|
||||
{
|
||||
switch (f) {
|
||||
switch (f)
|
||||
{
|
||||
case SW_SRC_ALPHA:
|
||||
case SW_ONE_MINUS_SRC_ALPHA:
|
||||
case SW_DST_ALPHA:
|
||||
@ -2829,6 +2832,7 @@ static bool sw_blend_factor_needs_alpha(SWfactor f)
|
||||
case SW_SRC_ALPHA_SATURATE: return true;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -723,7 +723,7 @@ void SetWindowIcon(Image image)
|
||||
TRACELOG(LOG_WARNING, "RGFW: Window icon image must be in R8G8B8A8 pixel format");
|
||||
return;
|
||||
}
|
||||
RGFW_window_setIcon(platform.window, (u8 *)image.data, image.width, image.height, 4);
|
||||
RGFW_window_setIcon(platform.window, (u8 *)image.data, image.width, image.height, RGFW_formatRGBA8);
|
||||
}
|
||||
|
||||
// Set icon for window
|
||||
@ -749,8 +749,8 @@ void SetWindowIcons(Image *images, int count)
|
||||
if ((smallIcon == NULL) || ((images[i].width < smallIcon->width) && (images[i].height > smallIcon->height))) smallIcon = &images[i];
|
||||
}
|
||||
|
||||
if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, smallIcon->width, smallIcon->height, 4, RGFW_iconWindow);
|
||||
if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, bigIcon->width, bigIcon->height, 4, RGFW_iconTaskbar);
|
||||
if (smallIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)smallIcon->data, smallIcon->width, smallIcon->height, RGFW_formatRGBA8, RGFW_iconWindow);
|
||||
if (bigIcon != NULL) RGFW_window_setIconEx(platform.window, (u8 *)bigIcon->data, bigIcon->width, bigIcon->height, RGFW_formatRGBA8, RGFW_iconTaskbar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1528,6 +1528,10 @@ void PollInputEvents(void)
|
||||
if ((width + borderLeft + borderRight != usableBounds.w) && (height + borderTop + borderBottom != usableBounds.h)) FLAG_CLEAR(CORE.Window.flags, FLAG_WINDOW_MAXIMIZED);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||
swResize(width, height);
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case SDL_WINDOWEVENT_ENTER: CORE.Input.Mouse.cursorOnScreen = true; break;
|
||||
|
||||
@ -1063,14 +1063,14 @@ Vector2 GetMonitorPosition(int monitor)
|
||||
// Get selected monitor width (currently used by monitor)
|
||||
int GetMonitorWidth(int monitor)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetMonitorWidth not implemented");
|
||||
//TRACELOG(LOG_WARNING, "GetMonitorWidth not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get selected monitor height (currently used by monitor)
|
||||
int GetMonitorHeight(int monitor)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetMonitorHeight not implemented");
|
||||
//TRACELOG(LOG_WARNING, "GetMonitorHeight not implemented");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1105,7 +1105,7 @@ const char *GetMonitorName(int monitor)
|
||||
// Get window position XY on monitor
|
||||
Vector2 GetWindowPosition(void)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "GetWindowPosition not implemented");
|
||||
//TRACELOG(LOG_WARNING, "GetWindowPosition not implemented");
|
||||
return (Vector2){ 0, 0 };
|
||||
}
|
||||
|
||||
@ -1760,13 +1760,31 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
|
||||
memset(CORE.Input.Keyboard.previousKeyState, 0, sizeof(CORE.Input.Keyboard.previousKeyState));
|
||||
memset(CORE.Input.Keyboard.currentKeyState, 0, sizeof(CORE.Input.Keyboard.currentKeyState));
|
||||
} break;
|
||||
case WM_SIZING:
|
||||
case WM_SIZING: // Sent to a window that the user is resizing
|
||||
{
|
||||
if (!(CORE.Window.flags & FLAG_WINDOW_RESIZABLE))
|
||||
TRACELOG(LOG_WARNING, "WIN32: WINDOW: Trying to resize a non-resizable window");
|
||||
if (CORE.Window.flags & FLAG_WINDOW_RESIZABLE)
|
||||
{
|
||||
//HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight);
|
||||
}
|
||||
|
||||
result = TRUE;
|
||||
} break;
|
||||
case WM_SIZE:
|
||||
{
|
||||
// WARNING: Don't trust the docs, they say this message can not be obtained if not calling DefWindowProc()
|
||||
// in response to WM_WINDOWPOSCHANGED but looks like when a window is created,
|
||||
// this message can be obtained without getting WM_WINDOWPOSCHANGED
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||
// WARNING: Waiting two frames before resizing because software-renderer backend is initilized with swInit() later
|
||||
// than InitPlatform(), that triggers WM_SIZE, so avoid crashing
|
||||
if (CORE.Time.frameCounter > 2) HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight);
|
||||
#else
|
||||
// NOTE: This message is only triggered on window creation
|
||||
HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight);
|
||||
#endif
|
||||
result = 0; // If an application processes WM_SIZE message, it should return zero
|
||||
} break;
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
DWORD style = MakeWindowStyle(platform.desiredFlags);
|
||||
@ -1865,19 +1883,13 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
|
||||
default: break;
|
||||
}
|
||||
} break;
|
||||
case WM_SIZE:
|
||||
{
|
||||
// WARNING: Don't trust the docs, they say this message can not be obtained if not calling DefWindowProc()
|
||||
// in response to WM_WINDOWPOSCHANGED but looks like when a window is created,
|
||||
// this message can be obtained without getting WM_WINDOWPOSCHANGED
|
||||
// WARNING: This call fails for Software-Renderer backend
|
||||
//HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight);
|
||||
} break;
|
||||
//case WM_MOVE
|
||||
//case WM_MOVE: break;
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
{
|
||||
WINDOWPOS *pos = (WINDOWPOS*)lparam;
|
||||
if (!(pos->flags & SWP_NOSIZE)) HandleWindowResize(hwnd, &platform.appScreenWidth, &platform.appScreenHeight);
|
||||
|
||||
DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
} break;
|
||||
case WM_GETDPISCALEDSIZE:
|
||||
{
|
||||
@ -2091,6 +2103,10 @@ static void HandleWindowResize(HWND hwnd, int *width, int *height)
|
||||
|
||||
CORE.Window.screenScale = MatrixScale( (float)CORE.Window.render.width/CORE.Window.screen.width,
|
||||
(float)CORE.Window.render.height/CORE.Window.screen.height, 1.0f);
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_SOFTWARE)
|
||||
swResize(clientSize.cx, clientSize.cy);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Update window style
|
||||
|
||||
@ -837,14 +837,8 @@ void SwapScreenBuffer(void)
|
||||
uint32_t height = mode->vdisplay;
|
||||
|
||||
// Dumb buffers use a fixed format based on bpp
|
||||
#if SW_COLOR_BUFFER_BITS == 24
|
||||
const uint32_t bpp = 32; // 32 bits per pixel (XRGB8888 format)
|
||||
const uint32_t depth = 24; // Color depth, here only 24 bits, alpha is not used
|
||||
#else
|
||||
// REVIEW: Not sure how it will be interpreted (RGB or RGBA?)
|
||||
const uint32_t bpp = SW_COLOR_BUFFER_BITS;
|
||||
const uint32_t depth = SW_COLOR_BUFFER_BITS;
|
||||
#endif
|
||||
|
||||
// Create a dumb buffer for software rendering
|
||||
struct drm_mode_create_dumb creq = { 0 };
|
||||
@ -899,7 +893,7 @@ void SwapScreenBuffer(void)
|
||||
|
||||
// Copy the software rendered buffer to the dumb buffer with scaling if needed
|
||||
// NOTE: RLSW will make a simple copy if the dimensions match
|
||||
swBlitFramebuffer(0, 0, width, height, 0, 0, width, height, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer);
|
||||
swBlitPixels(0, 0, width, height, 0, 0, width, height, SW_RGBA, SW_UNSIGNED_BYTE, dumbBuffer);
|
||||
|
||||
// Unmap the buffer
|
||||
munmap(dumbBuffer, creq.size);
|
||||
|
||||
12
src/raylib.h
12
src/raylib.h
@ -1161,8 +1161,8 @@ RLAPI int MakeDirectory(const char *dirPath); // Create di
|
||||
RLAPI bool ChangeDirectory(const char *dirPath); // Change working directory, return true on success
|
||||
RLAPI bool IsPathFile(const char *path); // Check if a given path is a file or a directory
|
||||
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
|
||||
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths
|
||||
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result
|
||||
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan
|
||||
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"
|
||||
RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload filepaths
|
||||
RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window
|
||||
RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths
|
||||
@ -1279,10 +1279,10 @@ RLAPI void DrawLineStrip(const Vector2 *points, int pointCount, Color color);
|
||||
RLAPI void DrawLineBezier(Vector2 startPos, Vector2 endPos, float thick, Color color); // Draw line segment cubic-bezier in-out interpolation
|
||||
RLAPI void DrawLineDashed(Vector2 startPos, Vector2 endPos, int dashSize, int spaceSize, Color color); // Draw a dashed line
|
||||
RLAPI void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
|
||||
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
|
||||
RLAPI void DrawCircleGradient(Vector2 center, float radius, Color inner, Color outer); // Draw a gradient-filled circle
|
||||
RLAPI void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw a piece of a circle
|
||||
RLAPI void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color); // Draw circle sector outline
|
||||
RLAPI void DrawCircleGradient(int centerX, int centerY, float radius, Color inner, Color outer); // Draw a gradient-filled circle
|
||||
RLAPI void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
|
||||
RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
|
||||
RLAPI void DrawCircleLinesV(Vector2 center, float radius, Color color); // Draw circle outline (Vector version)
|
||||
RLAPI void DrawEllipse(int centerX, int centerY, float radiusH, float radiusV, Color color); // Draw ellipse
|
||||
@ -1539,11 +1539,11 @@ RLAPI const char *TextSubtext(const char *text, int position, int length);
|
||||
RLAPI const char *TextRemoveSpaces(const char *text); // Remove text spaces, concat words
|
||||
RLAPI char *GetTextBetween(const char *text, const char *begin, const char *end); // Get text between two strings
|
||||
RLAPI char *TextReplace(const char *text, const char *search, const char *replacement); // Replace text string with new string
|
||||
RLAPI char *TextReplaceAlloc(const char *text, const char *search, const char *replacement); // Replace text string with new string, memory must be MemFree()
|
||||
RLAPI char *TextReplaceAlloc(const char *text, const char *search, const char *replacement); // Replace text string with new string, memory must be MemFree()
|
||||
RLAPI char *TextReplaceBetween(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings
|
||||
RLAPI char *TextReplaceBetweenAlloc(const char *text, const char *begin, const char *end, const char *replacement); // Replace text between two specific strings, memory must be MemFree()
|
||||
RLAPI char *TextInsert(const char *text, const char *insert, int position); // Insert text in a defined byte position
|
||||
RLAPI char *TextInsertAlloc(const char *text, const char *insert, int position); // Insert text in a defined byte position, memory must be MemFree()
|
||||
RLAPI char *TextInsertAlloc(const char *text, const char *insert, int position); // Insert text in a defined byte position, memory must be MemFree()
|
||||
RLAPI char *TextJoin(char **textList, int count, const char *delimiter); // Join text strings with delimiter
|
||||
RLAPI char **TextSplit(const char *text, char delimiter, int *count); // Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings
|
||||
RLAPI void TextAppend(char *text, const char *append, int *position); // Append text at specific position and move cursor
|
||||
|
||||
26
src/rcore.c
26
src/rcore.c
@ -267,15 +267,18 @@
|
||||
#define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record
|
||||
#endif
|
||||
|
||||
// File and directory scan filters
|
||||
// NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx()
|
||||
// WARNING: Custom file filters can be specified but following raylib IsFileExtension() convention: ".png;.wav;.glb"
|
||||
#ifndef FILE_FILTER_TAG_ALL
|
||||
#define FILE_FILTER_TAG_ALL "*.*" // Filter to include all file types and directories on directory scan
|
||||
#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx()
|
||||
#define FILE_FILTER_TAG_ALL "*.*" // Filter to include all file types and directories on scan
|
||||
#endif
|
||||
#ifndef FILE_FILTER_TAG_FILE_ONLY
|
||||
#define FILE_FILTER_TAG_FILE_ONLY "FILES*" // Filter to include all file types on directory scan
|
||||
#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx()
|
||||
#define FILE_FILTER_TAG_FILE_ONLY "FILES*" // Filter to include all file types on scan (no directories)
|
||||
#endif
|
||||
#ifndef FILE_FILTER_TAG_DIR_ONLY
|
||||
#define FILE_FILTER_TAG_DIR_ONLY "DIR*" // Filter to include directories on directory scan
|
||||
#endif // NOTE: Used in ScanDirectoryFiles(), LoadDirectoryFilesEx() and GetDirectoryFileCountEx()
|
||||
#define FILE_FILTER_TAG_DIR_ONLY "DIRS*" // Filter to include only directories on scan
|
||||
#endif
|
||||
|
||||
// Flags bitwise operation macros
|
||||
#define FLAG_SET(n, f) ((n) |= (f))
|
||||
@ -2720,17 +2723,18 @@ const char *GetApplicationDirectory(void)
|
||||
|
||||
// Load directory filepaths
|
||||
// NOTE: Base path is prepended to the scanned filepaths
|
||||
// WARNING: Directory is scanned twice, first time to get files count
|
||||
// No recursive scanning is done!
|
||||
// WARNING: Directory is scanned twice, first time to get paths count
|
||||
// Scanneed files and directories, no recursive/subdirs scanning
|
||||
FilePathList LoadDirectoryFiles(const char *dirPath)
|
||||
{
|
||||
return LoadDirectoryFilesEx(dirPath, FILE_FILTER_TAG_ALL, false);
|
||||
}
|
||||
|
||||
// Load directory filepaths with extension filtering and recursive directory scan
|
||||
// Use 'DIR*' to include directories on directory scan
|
||||
// Use '*.*' to include all file types and directories on directory scan
|
||||
// WARNING: Directory is scanned twice, first time to get files count
|
||||
// Use "*.*" to include all files and directories on scan
|
||||
// Use "FILES*" to include only files on scan
|
||||
// Use "DIRS*" to include only directories on scan
|
||||
// WARNING: Directory is scanned twice, first time to get paths count
|
||||
FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs)
|
||||
{
|
||||
FilePathList files = { 0 };
|
||||
|
||||
@ -1015,9 +1015,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_BONEWEIGHTS "vertexBoneWeights" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEWEIGHTS
|
||||
#endif
|
||||
#ifndef RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES
|
||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_BONEMATRICES "boneMatrices" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_BONEMATRICES
|
||||
#endif
|
||||
|
||||
#ifndef RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM
|
||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_INSTANCETRANSFORM "instanceTransform" // Bound by default to shader location: RL_DEFAULT_SHADER_ATTRIB_LOCATION_INSTANCETRANSFORM
|
||||
#endif
|
||||
|
||||
@ -324,6 +324,22 @@ void DrawCircleV(Vector2 center, float radius, Color color)
|
||||
DrawCircleSector(center, radius, 0, 360, 36, color);
|
||||
}
|
||||
|
||||
// Draw a gradient-filled circle
|
||||
void DrawCircleGradient(Vector2 center, float radius, Color inner, Color outer)
|
||||
{
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlColor4ub(inner.r, inner.g, inner.b, inner.a);
|
||||
rlVertex2f(center.x, center.y);
|
||||
rlColor4ub(outer.r, outer.g, outer.b, outer.a);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*(i + 10))*radius, center.y + sinf(DEG2RAD*(i + 10))*radius);
|
||||
rlColor4ub(outer.r, outer.g, outer.b, outer.a);
|
||||
rlVertex2f(center.x + cosf(DEG2RAD*i)*radius, center.y + sinf(DEG2RAD*i)*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
||||
// Draw a piece of a circle
|
||||
void DrawCircleSector(Vector2 center, float radius, float startAngle, float endAngle, int segments, Color color)
|
||||
{
|
||||
@ -473,22 +489,6 @@ void DrawCircleSectorLines(Vector2 center, float radius, float startAngle, float
|
||||
rlEnd();
|
||||
}
|
||||
|
||||
// Draw a gradient-filled circle
|
||||
void DrawCircleGradient(int centerX, int centerY, float radius, Color inner, Color outer)
|
||||
{
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlColor4ub(inner.r, inner.g, inner.b, inner.a);
|
||||
rlVertex2f((float)centerX, (float)centerY);
|
||||
rlColor4ub(outer.r, outer.g, outer.b, outer.a);
|
||||
rlVertex2f((float)centerX + cosf(DEG2RAD*(i + 10))*radius, (float)centerY + sinf(DEG2RAD*(i + 10))*radius);
|
||||
rlColor4ub(outer.r, outer.g, outer.b, outer.a);
|
||||
rlVertex2f((float)centerX + cosf(DEG2RAD*i)*radius, (float)centerY + sinf(DEG2RAD*i)*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
|
||||
// Draw circle outline
|
||||
void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
||||
{
|
||||
|
||||
@ -4685,7 +4685,7 @@
|
||||
},
|
||||
{
|
||||
"name": "LoadDirectoryFiles",
|
||||
"description": "Load directory filepaths",
|
||||
"description": "Load directory filepaths, files and directories, no subdirs scan",
|
||||
"returnType": "FilePathList",
|
||||
"params": [
|
||||
{
|
||||
@ -4696,7 +4696,7 @@
|
||||
},
|
||||
{
|
||||
"name": "LoadDirectoryFilesEx",
|
||||
"description": "Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result",
|
||||
"description": "Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"",
|
||||
"returnType": "FilePathList",
|
||||
"params": [
|
||||
{
|
||||
@ -5698,6 +5698,48 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircleV",
|
||||
"description": "Draw a color-filled circle (Vector version)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "center"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "radius"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircleGradient",
|
||||
"description": "Draw a gradient-filled circle",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "center"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "radius"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "inner"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "outer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircleSector",
|
||||
"description": "Draw a piece of a circle",
|
||||
@ -5760,52 +5802,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircleGradient",
|
||||
"description": "Draw a gradient-filled circle",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "int",
|
||||
"name": "centerX"
|
||||
},
|
||||
{
|
||||
"type": "int",
|
||||
"name": "centerY"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "radius"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "inner"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "outer"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircleV",
|
||||
"description": "Draw a color-filled circle (Vector version)",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "Vector2",
|
||||
"name": "center"
|
||||
},
|
||||
{
|
||||
"type": "float",
|
||||
"name": "radius"
|
||||
},
|
||||
{
|
||||
"type": "Color",
|
||||
"name": "color"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "DrawCircleLines",
|
||||
"description": "Draw circle outline",
|
||||
|
||||
@ -4199,7 +4199,7 @@ return {
|
||||
},
|
||||
{
|
||||
name = "LoadDirectoryFiles",
|
||||
description = "Load directory filepaths",
|
||||
description = "Load directory filepaths, files and directories, no subdirs scan",
|
||||
returnType = "FilePathList",
|
||||
params = {
|
||||
{type = "const char *", name = "dirPath"}
|
||||
@ -4207,7 +4207,7 @@ return {
|
||||
},
|
||||
{
|
||||
name = "LoadDirectoryFilesEx",
|
||||
description = "Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result",
|
||||
description = "Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"",
|
||||
returnType = "FilePathList",
|
||||
params = {
|
||||
{type = "const char *", name = "basePath"},
|
||||
@ -4861,6 +4861,27 @@ return {
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircleV",
|
||||
description = "Draw a color-filled circle (Vector version)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "center"},
|
||||
{type = "float", name = "radius"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircleGradient",
|
||||
description = "Draw a gradient-filled circle",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "center"},
|
||||
{type = "float", name = "radius"},
|
||||
{type = "Color", name = "inner"},
|
||||
{type = "Color", name = "outer"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircleSector",
|
||||
description = "Draw a piece of a circle",
|
||||
@ -4887,28 +4908,6 @@ return {
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircleGradient",
|
||||
description = "Draw a gradient-filled circle",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "int", name = "centerX"},
|
||||
{type = "int", name = "centerY"},
|
||||
{type = "float", name = "radius"},
|
||||
{type = "Color", name = "inner"},
|
||||
{type = "Color", name = "outer"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircleV",
|
||||
description = "Draw a color-filled circle (Vector version)",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Vector2", name = "center"},
|
||||
{type = "float", name = "radius"},
|
||||
{type = "Color", name = "color"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "DrawCircleLines",
|
||||
description = "Draw circle outline",
|
||||
|
||||
@ -1784,12 +1784,12 @@ Function 145: IsFileNameValid() (1 input parameters)
|
||||
Function 146: LoadDirectoryFiles() (1 input parameters)
|
||||
Name: LoadDirectoryFiles
|
||||
Return type: FilePathList
|
||||
Description: Load directory filepaths
|
||||
Description: Load directory filepaths, files and directories, no subdirs scan
|
||||
Param[1]: dirPath (type: const char *)
|
||||
Function 147: LoadDirectoryFilesEx() (3 input parameters)
|
||||
Name: LoadDirectoryFilesEx
|
||||
Return type: FilePathList
|
||||
Description: Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result
|
||||
Description: Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"
|
||||
Param[1]: basePath (type: const char *)
|
||||
Param[2]: filter (type: const char *)
|
||||
Param[3]: scanSubdirs (type: bool)
|
||||
@ -2262,7 +2262,22 @@ Function 230: DrawCircle() (4 input parameters)
|
||||
Param[2]: centerY (type: int)
|
||||
Param[3]: radius (type: float)
|
||||
Param[4]: color (type: Color)
|
||||
Function 231: DrawCircleSector() (6 input parameters)
|
||||
Function 231: DrawCircleV() (3 input parameters)
|
||||
Name: DrawCircleV
|
||||
Return type: void
|
||||
Description: Draw a color-filled circle (Vector version)
|
||||
Param[1]: center (type: Vector2)
|
||||
Param[2]: radius (type: float)
|
||||
Param[3]: color (type: Color)
|
||||
Function 232: DrawCircleGradient() (4 input parameters)
|
||||
Name: DrawCircleGradient
|
||||
Return type: void
|
||||
Description: Draw a gradient-filled circle
|
||||
Param[1]: center (type: Vector2)
|
||||
Param[2]: radius (type: float)
|
||||
Param[3]: inner (type: Color)
|
||||
Param[4]: outer (type: Color)
|
||||
Function 233: DrawCircleSector() (6 input parameters)
|
||||
Name: DrawCircleSector
|
||||
Return type: void
|
||||
Description: Draw a piece of a circle
|
||||
@ -2272,7 +2287,7 @@ Function 231: DrawCircleSector() (6 input parameters)
|
||||
Param[4]: endAngle (type: float)
|
||||
Param[5]: segments (type: int)
|
||||
Param[6]: color (type: Color)
|
||||
Function 232: DrawCircleSectorLines() (6 input parameters)
|
||||
Function 234: DrawCircleSectorLines() (6 input parameters)
|
||||
Name: DrawCircleSectorLines
|
||||
Return type: void
|
||||
Description: Draw circle sector outline
|
||||
@ -2282,22 +2297,6 @@ Function 232: DrawCircleSectorLines() (6 input parameters)
|
||||
Param[4]: endAngle (type: float)
|
||||
Param[5]: segments (type: int)
|
||||
Param[6]: color (type: Color)
|
||||
Function 233: DrawCircleGradient() (5 input parameters)
|
||||
Name: DrawCircleGradient
|
||||
Return type: void
|
||||
Description: Draw a gradient-filled circle
|
||||
Param[1]: centerX (type: int)
|
||||
Param[2]: centerY (type: int)
|
||||
Param[3]: radius (type: float)
|
||||
Param[4]: inner (type: Color)
|
||||
Param[5]: outer (type: Color)
|
||||
Function 234: DrawCircleV() (3 input parameters)
|
||||
Name: DrawCircleV
|
||||
Return type: void
|
||||
Description: Draw a color-filled circle (Vector version)
|
||||
Param[1]: center (type: Vector2)
|
||||
Param[2]: radius (type: float)
|
||||
Param[3]: color (type: Color)
|
||||
Function 235: DrawCircleLines() (4 input parameters)
|
||||
Name: DrawCircleLines
|
||||
Return type: void
|
||||
|
||||
@ -1122,10 +1122,10 @@
|
||||
<Function name="IsFileNameValid" retType="bool" paramCount="1" desc="Check if fileName is valid for the platform/OS">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
</Function>
|
||||
<Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths">
|
||||
<Function name="LoadDirectoryFiles" retType="FilePathList" paramCount="1" desc="Load directory filepaths, files and directories, no subdirs scan">
|
||||
<Param type="const char *" name="dirPath" desc="" />
|
||||
</Function>
|
||||
<Function name="LoadDirectoryFilesEx" retType="FilePathList" paramCount="3" desc="Load directory filepaths with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result">
|
||||
<Function name="LoadDirectoryFilesEx" retType="FilePathList" paramCount="3" desc="Load directory filepaths with extension filtering and subdir scan; some filters available: "*.*", "FILES*", "DIRS*"">
|
||||
<Param type="const char *" name="basePath" desc="" />
|
||||
<Param type="const char *" name="filter" desc="" />
|
||||
<Param type="bool" name="scanSubdirs" desc="" />
|
||||
@ -1409,6 +1409,17 @@
|
||||
<Param type="float" name="radius" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircleV" retType="void" paramCount="3" desc="Draw a color-filled circle (Vector version)">
|
||||
<Param type="Vector2" name="center" desc="" />
|
||||
<Param type="float" name="radius" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircleGradient" retType="void" paramCount="4" desc="Draw a gradient-filled circle">
|
||||
<Param type="Vector2" name="center" desc="" />
|
||||
<Param type="float" name="radius" desc="" />
|
||||
<Param type="Color" name="inner" desc="" />
|
||||
<Param type="Color" name="outer" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircleSector" retType="void" paramCount="6" desc="Draw a piece of a circle">
|
||||
<Param type="Vector2" name="center" desc="" />
|
||||
<Param type="float" name="radius" desc="" />
|
||||
@ -1425,18 +1436,6 @@
|
||||
<Param type="int" name="segments" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircleGradient" retType="void" paramCount="5" desc="Draw a gradient-filled circle">
|
||||
<Param type="int" name="centerX" desc="" />
|
||||
<Param type="int" name="centerY" desc="" />
|
||||
<Param type="float" name="radius" desc="" />
|
||||
<Param type="Color" name="inner" desc="" />
|
||||
<Param type="Color" name="outer" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircleV" retType="void" paramCount="3" desc="Draw a color-filled circle (Vector version)">
|
||||
<Param type="Vector2" name="center" desc="" />
|
||||
<Param type="float" name="radius" desc="" />
|
||||
<Param type="Color" name="color" desc="" />
|
||||
</Function>
|
||||
<Function name="DrawCircleLines" retType="void" paramCount="4" desc="Draw circle outline">
|
||||
<Param type="int" name="centerX" desc="" />
|
||||
<Param type="int" name="centerY" desc="" />
|
||||
|
||||
Reference in New Issue
Block a user