diff --git a/ROADMAP.md b/ROADMAP.md index 10754e52b..91d2299c3 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -23,6 +23,7 @@ _Current version of raylib is complete and functional but there is always room f - [ ] `rlsw`: Software renderer optimizations: mipmaps, platform-specific SIMD - [ ] `rtextures`: Consider moving N-patch system to separate example - [ ] `rtextures`: Review blending modes system, provide more options or better samples + - [ ] `rtext`: Investigate the recently opened [`Slug`](https://sluglibrary.com/) font rendering algorithm - [ ] `raudio`: Support microphone input, basic API to read microphone - [ ] `rltexgpu`: Improve compressed textures support, loading and saving, improve KTX 2.0 - [ ] `rlobj`: Create OBJ loader, supporting material file separately (low priority) diff --git a/examples/README.md b/examples/README.md index 43e2dcc63..d48641528 100644 --- a/examples/README.md +++ b/examples/README.md @@ -223,7 +223,7 @@ Examples using raylib models functionality, including models loading/generation ### category: shaders [35] -Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.c) module. +Examples using raylib shaders functionality, including shaders loading, parameters configuration and drawing using them (model shaders and postprocessing shaders). This functionality is directly provided by raylib [rlgl](../src/rlgl.h) module. | example | image | difficulty
level | version
created | last version
updated | original
developer | |-----------|--------|:-------------------:|:------------------:|:-----------------------:|:----------------------| diff --git a/examples/core/core_random_sequence.c b/examples/core/core_random_sequence.c index 19d44461e..32ec3001b 100644 --- a/examples/core/core_random_sequence.c +++ b/examples/core/core_random_sequence.c @@ -111,7 +111,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - free(rectangles); + RL_FREE(rectangles); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/models/models_yaw_pitch_roll.c b/examples/models/models_yaw_pitch_roll.c index c19aafdcd..af0f06daf 100644 --- a/examples/models/models_yaw_pitch_roll.c +++ b/examples/models/models_yaw_pitch_roll.c @@ -41,6 +41,9 @@ int main(void) Model model = LoadModel("resources/models/obj/plane.obj"); // Load model Texture2D texture = LoadTexture("resources/models/obj/plane_diffuse.png"); // Load model texture + + SetTextureWrap(texture, TEXTURE_WRAP_REPEAT); // Force Repeat to avoid issue on Web version + model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture float pitch = 0.0f; diff --git a/examples/shapes/shapes_ball_physics.c b/examples/shapes/shapes_ball_physics.c index f01a7c8e1..9c18ab66e 100644 --- a/examples/shapes/shapes_ball_physics.c +++ b/examples/shapes/shapes_ball_physics.c @@ -17,15 +17,19 @@ #include "raylib.h" -#include -#include +#include // Required for: malloc(), free() +#include // Required for: hypot() -#define MAX_BALLS 5000 // Maximum quantity of balls +#define MAX_BALLS 5000 // Maximum quantity of balls +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Ball data type typedef struct Ball { - Vector2 pos; // Position - Vector2 vel; // Velocity - Vector2 ppos; // Previous position + Vector2 position; + Vector2 speed; + Vector2 prevPosition; float radius; float friction; float elasticity; @@ -45,24 +49,27 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shapes] example - ball physics"); - Ball balls[MAX_BALLS] = {{ - .pos = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f }, - .vel = { 200, 200 }, - .ppos = { 0 }, + Ball *balls = (Ball*)RL_MALLOC(sizeof(Ball)*MAX_BALLS); + + // Init first ball in the array + balls[0] = (Ball){ + .position = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f }, + .speed = { 200, 200 }, + .prevPosition = { 0 }, .radius = 40, .friction = 0.99f, .elasticity = 0.9f, .color = BLUE, .grabbed = false - }}; + }; int ballCount = 1; - Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed - Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd + Ball *grabbedBall = NULL; // A pointer to the current ball that is grabbed + Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd - float gravity = 100; // World gravity + float gravity = 100; // World gravity - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //--------------------------------------------------------------------------------------- // Main game loop @@ -79,8 +86,8 @@ int main(void) for (int i = ballCount - 1; i >= 0; i--) { Ball *ball = &balls[i]; - pressOffset.x = mousePos.x - ball->pos.x; - pressOffset.y = mousePos.y - ball->pos.y; + pressOffset.x = mousePos.x - ball->position.x; + pressOffset.y = mousePos.y - ball->position.y; // If the distance between the ball position and the mouse press position // is less than or equal to the ball radius, the event occurred inside the ball @@ -109,9 +116,9 @@ int main(void) if (ballCount < MAX_BALLS) { balls[ballCount++] = (Ball){ - .pos = mousePos, - .vel = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) }, - .ppos = { 0 }, + .position = mousePos, + .speed = { (float)GetRandomValue(-300, 300), (float)GetRandomValue(-300, 300) }, + .prevPosition = { 0 }, .radius = 20.0f + (float)GetRandomValue(0, 30), .friction = 0.99f, .elasticity = 0.9f, @@ -126,7 +133,7 @@ int main(void) { for (int i = 0; i < ballCount; i++) { - if (!balls[i].grabbed) balls[i].vel = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) }; + if (!balls[i].grabbed) balls[i].speed = (Vector2){ (float)GetRandomValue(-2000, 2000), (float)GetRandomValue(-2000, 2000) }; } } @@ -142,49 +149,49 @@ int main(void) if (!ball->grabbed) { // Ball repositioning using the velocity - ball->pos.x += ball->vel.x * delta; - ball->pos.y += ball->vel.y * delta; + ball->position.x += ball->speed.x * delta; + ball->position.y += ball->speed.y * delta; // Does the ball hit the screen right boundary? - if ((ball->pos.x + ball->radius) >= screenWidth) + if ((ball->position.x + ball->radius) >= screenWidth) { - ball->pos.x = screenWidth - ball->radius; // Ball repositioning - ball->vel.x = -ball->vel.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit + ball->position.x = screenWidth - ball->radius; // Ball repositioning + ball->speed.x = -ball->speed.x*ball->elasticity; // Elasticity makes the ball lose 10% of its velocity on hit } // Does the ball hit the screen left boundary? - else if ((ball->pos.x - ball->radius) <= 0) + else if ((ball->position.x - ball->radius) <= 0) { - ball->pos.x = ball->radius; - ball->vel.x = -ball->vel.x*ball->elasticity; + ball->position.x = ball->radius; + ball->speed.x = -ball->speed.x*ball->elasticity; } // The same for y axis - if ((ball->pos.y + ball->radius) >= screenHeight) + if ((ball->position.y + ball->radius) >= screenHeight) { - ball->pos.y = screenHeight - ball->radius; - ball->vel.y = -ball->vel.y*ball->elasticity; + ball->position.y = screenHeight - ball->radius; + ball->speed.y = -ball->speed.y*ball->elasticity; } - else if ((ball->pos.y - ball->radius) <= 0) + else if ((ball->position.y - ball->radius) <= 0) { - ball->pos.y = ball->radius; - ball->vel.y = -ball->vel.y*ball->elasticity; + ball->position.y = ball->radius; + ball->speed.y = -ball->speed.y*ball->elasticity; } // Friction makes the ball lose 1% of its velocity each frame - ball->vel.x = ball->vel.x*ball->friction; + ball->speed.x = ball->speed.x*ball->friction; // Gravity affects only the y axis - ball->vel.y = ball->vel.y*ball->friction + gravity; + ball->speed.y = ball->speed.y*ball->friction + gravity; } else { // Ball repositioning using the mouse position - ball->pos.x = mousePos.x - pressOffset.x; - ball->pos.y = mousePos.y - pressOffset.y; + ball->position.x = mousePos.x - pressOffset.x; + ball->position.y = mousePos.y - pressOffset.y; // While the ball is grabbed, recalculates its velocity - ball->vel.x = (ball->pos.x - ball->ppos.x)/delta; - ball->vel.y = (ball->pos.y - ball->ppos.y)/delta; - ball->ppos = ball->pos; + ball->speed.x = (ball->position.x - ball->prevPosition.x)/delta; + ball->speed.y = (ball->position.y - ball->prevPosition.y)/delta; + ball->prevPosition = ball->position; } } //---------------------------------------------------------------------------------- @@ -197,8 +204,8 @@ int main(void) for (int i = 0; i < ballCount; i++) { - DrawCircleV(balls[i].pos, balls[i].radius, balls[i].color); - DrawCircleLinesV(balls[i].pos, balls[i].radius, BLACK); + DrawCircleV(balls[i].position, balls[i].radius, balls[i].color); + DrawCircleLinesV(balls[i].position, balls[i].radius, BLACK); } DrawText("grab a ball by pressing with the mouse and throw it by releasing", 10, 10, 10, DARKGRAY); @@ -214,6 +221,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- + RL_FREE(balls); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/examples/shapes/shapes_bouncing_ball.png b/examples/shapes/shapes_bouncing_ball.png index 9d98e3a88..a9555b5c7 100644 Binary files a/examples/shapes/shapes_bouncing_ball.png and b/examples/shapes/shapes_bouncing_ball.png differ diff --git a/examples/text/text_codepoints_loading.c b/examples/text/text_codepoints_loading.c index 1cd82d60e..1da8cf93f 100644 --- a/examples/text/text_codepoints_loading.c +++ b/examples/text/text_codepoints_loading.c @@ -61,7 +61,7 @@ int main(void) SetTextLineSpacing(20); // Set line spacing for multiline text (when line breaks are included '\n') // Free codepoints, atlas has already been generated - free(codepointsNoDups); + RL_FREE(codepointsNoDups); bool showFontAtlas = false; @@ -139,7 +139,7 @@ int main(void) static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointsResultCount) { int codepointsNoDupsCount = codepointCount; - int *codepointsNoDups = (int *)calloc(codepointCount, sizeof(int)); + int *codepointsNoDups = (int *)RL_CALLOC(codepointCount, sizeof(int)); memcpy(codepointsNoDups, codepoints, codepointCount*sizeof(int)); // Remove duplicates diff --git a/examples/textures/textures_bunnymark.c b/examples/textures/textures_bunnymark.c index a04741227..64e55db43 100644 --- a/examples/textures/textures_bunnymark.c +++ b/examples/textures/textures_bunnymark.c @@ -47,7 +47,7 @@ int main(void) // Load bunny texture Texture2D texBunny = LoadTexture("resources/raybunny.png"); - Bunny *bunnies = (Bunny *)malloc(MAX_BUNNIES*sizeof(Bunny)); // Bunnies array + Bunny *bunnies = (Bunny *)RL_MALLOC(MAX_BUNNIES*sizeof(Bunny)); // Bunnies array int bunniesCount = 0; // Bunnies counter @@ -126,7 +126,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - free(bunnies); // Unload bunnies data array + RL_FREE(bunnies); // Unload bunnies data array UnloadTexture(texBunny); // Unload bunny texture diff --git a/examples/textures/textures_fog_of_war.c b/examples/textures/textures_fog_of_war.c index 1354d7124..e4ed2b60a 100644 --- a/examples/textures/textures_fog_of_war.c +++ b/examples/textures/textures_fog_of_war.c @@ -51,8 +51,8 @@ int main(void) // NOTE: We can have up to 256 values for tile ids and for tile fog state, // probably we don't need that many values for fog state, it can be optimized // to use only 2 bits per fog state (reducing size by 4) but logic will be a bit more complex - map.tileIds = (unsigned char *)calloc(map.tilesX*map.tilesY, sizeof(unsigned char)); - map.tileFog = (unsigned char *)calloc(map.tilesX*map.tilesY, sizeof(unsigned char)); + map.tileIds = (unsigned char *)RL_CALLOC(map.tilesX*map.tilesY, sizeof(unsigned char)); + map.tileFog = (unsigned char *)RL_CALLOC(map.tilesX*map.tilesY, sizeof(unsigned char)); // Load map tiles (generating 2 random tile ids for testing) // NOTE: Map tile ids should be probably loaded from an external map file @@ -149,8 +149,8 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - free(map.tileIds); // Free allocated map tile ids - free(map.tileFog); // Free allocated map tile fog state + RL_FREE(map.tileIds); // Free allocated map tile ids + RL_FREE(map.tileFog); // Free allocated map tile fog state UnloadRenderTexture(fogOfWar); // Unload render texture diff --git a/examples/textures/textures_raw_data.c b/examples/textures/textures_raw_data.c index c38983b53..49efc890e 100644 --- a/examples/textures/textures_raw_data.c +++ b/examples/textures/textures_raw_data.c @@ -17,8 +17,6 @@ #include "raylib.h" -#include // Required for: malloc() and free() - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -39,26 +37,31 @@ int main(void) UnloadImage(fudesumiRaw); // Unload CPU (RAM) image data // Generate a checked texture by code - int width = 960; - int height = 480; + int imWidth = 960; + int imHeight = 480; // Dynamic memory allocation to store pixels data (Color type) - Color *pixels = (Color *)malloc(width*height*sizeof(Color)); + // WARNING: Using raylib provided MemAlloc() that uses default raylib + // internal memory allocator, so this data can be freed using UnloadImage() + // that also uses raylib internal memory de-allocator + Color *pixels = (Color *)MemAlloc(imWidth*imHeight*sizeof(Color)); - for (int y = 0; y < height; y++) + for (int y = 0; y < imHeight; y++) { - for (int x = 0; x < width; x++) + for (int x = 0; x < imWidth; x++) { - if (((x/32+y/32)/1)%2 == 0) pixels[y*width + x] = ORANGE; - else pixels[y*width + x] = GOLD; + if (((x/32+y/32)/1)%2 == 0) pixels[y*imWidth + x] = ORANGE; + else pixels[y*imWidth + x] = GOLD; } } // Load pixels data into an image structure and create texture + // NOTE: We can assign pixels directly to data because Color is R8G8B8A8 + // data structure defining that pixelformat, format must be set properly Image checkedIm = { - .data = pixels, // We can assign pixels directly to data - .width = width, - .height = height, + .data = pixels, + .width = imWidth, + .height = imHeight, .format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, .mipmaps = 1 }; diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 7817c7874..fb1fc6cf6 100755 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -1447,28 +1447,26 @@ void PollInputEvents(void) } break; case RGFW_mousePosChanged: { - float event_x = 0.0f, event_y = 0.0f; + float mouseX = 0.0f; + float mouseY = 0.0f; if (RGFW_window_isCaptured(platform.window)) { - event_x = (float)rgfw_event.mouse.vecX; - event_y = (float)rgfw_event.mouse.vecY; + mouseX = (float)rgfw_event.mouse.vecX; + mouseY = (float)rgfw_event.mouse.vecY; } else { - event_x = (float)rgfw_event.mouse.x; - event_y = (float)rgfw_event.mouse.y; + mouseX = (float)rgfw_event.mouse.x; + mouseY = (float)rgfw_event.mouse.y; } #if defined(__EMSCRIPTEN__) - { - double canvasWidth = 0.0; - double canvasHeight = 0.0; - emscripten_get_element_css_size("#canvas", &canvasWidth, &canvasHeight); - event_x *= ((float)GetScreenWidth() / (float)canvasWidth); - event_y *= ((float)GetScreenHeight() / (float)canvasHeight); - } + double canvasWidth = 0.0; + double canvasHeight = 0.0; + emscripten_get_element_css_size("#canvas", &canvasWidth, &canvasHeight); + mouseX *= ((float)GetScreenWidth()/(float)canvasWidth); + mouseY *= ((float)GetScreenHeight()/(float)canvasHeight); #endif - if (RGFW_window_isCaptured(platform.window)) { CORE.Input.Mouse.currentPosition.x += event_x; diff --git a/src/rcore.c b/src/rcore.c index 5cdc8aca1..894e00832 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2274,14 +2274,14 @@ int FileCopy(const char *srcPath, const char *dstPath) // NOTE: If dst directories do not exists they are created int FileMove(const char *srcPath, const char *dstPath) { - int result = 0; + int result = -1; if (FileExists(srcPath)) { - FileCopy(srcPath, dstPath); - FileRemove(srcPath); + if (FileCopy(srcPath, dstPath) == 0) result = FileRemove(srcPath); + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to copy file to [%s]", srcPath, dstPath); } - else result = -1; + else TRACELOG(LOG_WARNING, "FILEIO: [%s] Source file does not exist", srcPath); return result; } diff --git a/src/rlgl.h b/src/rlgl.h index 13c037132..ce10b2f64 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -880,7 +880,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad #elif defined(GRAPHICS_API_OPENGL_ES2) // NOTE: OpenGL ES 2.0 can be enabled on Desktop platforms, // in that case, functions are loaded from a custom glad for OpenGL ES 2.0 - // TODO: OpenGL ES 2.0 support shouldn't be platform-dependant, neither require GLAD + // TODO: OpenGL ES 2.0 support shouldn't be platform-dependent, neither require GLAD #if defined(PLATFORM_DESKTOP_GLFW) || defined(PLATFORM_DESKTOP_SDL) #define GLAD_GLES2_IMPLEMENTATION #include "external/glad_gles2.h" @@ -893,7 +893,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad // It seems OpenGL ES 2.0 instancing entry points are not defined on Raspberry Pi // provided headers (despite being defined in official Khronos GLES2 headers) - // TODO: Avoid raylib platform-dependant code on rlgl, it should be a completely portable library + // TODO: Avoid raylib platform-dependent code on rlgl, it should be a completely portable library #if defined(PLATFORM_DRM) typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei primcount); @@ -1392,7 +1392,7 @@ void rlFrustum(double left, double right, double bottom, double top, double znea void rlOrtho(double left, double right, double bottom, double top, double znear, double zfar) { // NOTE: If left-right and top-botton values are equal it could create a division by zero, - // response to it is platform/compiler dependant + // response to it is platform/compiler dependent Matrix matOrtho = { 0 }; float rl = (float)(right - left); @@ -1509,7 +1509,7 @@ void rlBegin(int mode) // Finish vertex providing void rlEnd(void) { - // NOTE: Depth increment is dependant on rlOrtho(): z-near and z-far values, + // NOTE: Depth increment is dependent on rlOrtho(): z-near and z-far values, // as well as depth buffer bit-depth (16bit or 24bit or 32bit) // Correct increment formula would be: depthInc = (zfar - znear)/pow(2, bits) RLGL.currentBatch->currentDepth += (1.0f/20000.0f); @@ -1902,7 +1902,7 @@ void rlBindFramebuffer(unsigned int target, unsigned int framebuffer) void rlActiveDrawBuffers(int count) { #if (defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES3)) - // NOTE: Maximum number of draw buffers supported is implementation dependant, + // NOTE: Maximum number of draw buffers supported is implementation dependent, // it can be queried with glGet*() but it must be at least 8 //GLint maxDrawBuffers = 0; //glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 49d4dce9a..e4881b633 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1669,7 +1669,7 @@ int main(int argc, char *argv[]) FileRemove(TextFormat("%s/%s/%s.original.c", exBasePath, exCategory, exName)); // STEP 3: Run example with required arguments - // NOTE: Not easy to retrieve process return value from system(), it's platform dependant + // NOTE: Not easy to retrieve process return value from system(), it's platform dependent ChangeDirectory(TextFormat("%s/%s", exBasePath, exCategory)); #if defined(_WIN32)