diff --git a/.github/workflows/build_android.yml b/.github/workflows/build_android.yml index 80520d0b2..6993eb292 100644 --- a/.github/workflows/build_android.yml +++ b/.github/workflows/build_android.yml @@ -84,8 +84,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.tar.gz - path: ./build/${{ env.RELEASE_NAME }}.tar.gz + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.tar.gz - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml index a76345b90..b101750bc 100644 --- a/.github/workflows/build_linux.yml +++ b/.github/workflows/build_linux.yml @@ -114,8 +114,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.tar.gz - path: ./build/${{ env.RELEASE_NAME }}.tar.gz + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.tar.gz - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_macos.yml b/.github/workflows/build_macos.yml index 965efe249..f27140107 100644 --- a/.github/workflows/build_macos.yml +++ b/.github/workflows/build_macos.yml @@ -101,8 +101,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.tar.gz - path: ./build/${{ env.RELEASE_NAME }}.tar.gz + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.tar.gz - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_webassembly.yml b/.github/workflows/build_webassembly.yml index 32ae94215..d79b12b1c 100644 --- a/.github/workflows/build_webassembly.yml +++ b/.github/workflows/build_webassembly.yml @@ -71,8 +71,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.zip - path: ./build/${{ env.RELEASE_NAME }}.zip + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.zip - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/.github/workflows/build_windows.yml b/.github/workflows/build_windows.yml index 7a92c208a..988428403 100644 --- a/.github/workflows/build_windows.yml +++ b/.github/workflows/build_windows.yml @@ -142,8 +142,10 @@ jobs: - name: Upload Artifacts uses: actions/upload-artifact@v4 with: - name: ${{ env.RELEASE_NAME }}.zip - path: ./build/${{ env.RELEASE_NAME }}.zip + name: ${{ env.RELEASE_NAME }} + path: | + ./build/${{ env.RELEASE_NAME }} + !./build/${{ env.RELEASE_NAME }}.zip - name: Upload Artifact to Release uses: softprops/action-gh-release@v1 diff --git a/examples/core/core_2d_camera_platformer.c b/examples/core/core_2d_camera_platformer.c index 45bad4015..49d0a940c 100644 --- a/examples/core/core_2d_camera_platformer.c +++ b/examples/core/core_2d_camera_platformer.c @@ -226,10 +226,10 @@ void UpdateCameraCenterInsideMap(Camera2D *camera, Player *player, EnvItem *envI Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, *camera); Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, *camera); - if (max.x < width) camera->offset.x = width - (max.x - width/2); - if (max.y < height) camera->offset.y = height - (max.y - height/2); - if (min.x > 0) camera->offset.x = width/2 - min.x; - if (min.y > 0) camera->offset.y = height/2 - min.y; + if (max.x < width) camera->offset.x = width - (max.x - (float)width/2); + if (max.y < height) camera->offset.y = height - (max.y - (float)height/2); + if (min.x > 0) camera->offset.x = (float)width/2 - min.x; + if (min.y > 0) camera->offset.y = (float)height/2 - min.y; } void UpdateCameraCenterSmoothFollow(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height) diff --git a/examples/core/core_automation_events.c b/examples/core/core_automation_events.c index b98b37c69..50204187f 100644 --- a/examples/core/core_automation_events.c +++ b/examples/core/core_automation_events.c @@ -225,10 +225,10 @@ int main(void) Vector2 max = GetWorldToScreen2D((Vector2){ maxX, maxY }, camera); Vector2 min = GetWorldToScreen2D((Vector2){ minX, minY }, camera); - if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - screenWidth/2); - if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - screenHeight/2); - if (min.x > 0) camera.offset.x = screenWidth/2 - min.x; - if (min.y > 0) camera.offset.y = screenHeight/2 - min.y; + if (max.x < screenWidth) camera.offset.x = screenWidth - (max.x - (float)screenWidth/2); + if (max.y < screenHeight) camera.offset.y = screenHeight - (max.y - (float)screenHeight/2); + if (min.x > 0) camera.offset.x = (float)screenWidth/2 - min.x; + if (min.y > 0) camera.offset.y = (float)screenHeight/2 - min.y; //---------------------------------------------------------------------------------- // Events management diff --git a/examples/core/core_viewport_scaling.c b/examples/core/core_viewport_scaling.c index 6ff5ac9c4..4a608e96d 100644 --- a/examples/core/core_viewport_scaling.c +++ b/examples/core/core_viewport_scaling.c @@ -216,7 +216,7 @@ static void KeepAspectCenteredInteger(int screenWidth, int screenHeight, int gam static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { - const float resizeRatio = (float)(screenHeight/gameHeight); + const float resizeRatio = (float)screenHeight/gameHeight; sourceRect->x = 0.0f; sourceRect->y = 0.0f; sourceRect->width = (float)(int)(screenWidth/resizeRatio); @@ -230,7 +230,7 @@ static void KeepHeightCenteredInteger(int screenWidth, int screenHeight, int gam static void KeepWidthCenteredInteger(int screenWidth, int screenHeight, int gameWidth, int gameHeight, Rectangle *sourceRect, Rectangle *destRect) { - const float resizeRatio = (float)(screenWidth/gameWidth); + const float resizeRatio = (float)screenWidth/gameWidth; sourceRect->x = 0.0f; sourceRect->y = 0.0f; sourceRect->width = (float)gameWidth; diff --git a/examples/core/msf_gif.h b/examples/core/msf_gif.h index bc2c6edef..6aa11fdbd 100644 --- a/examples/core/msf_gif.h +++ b/examples/core/msf_gif.h @@ -413,7 +413,7 @@ static MsfGifBuffer * msf_compress_frame(void * allocContext, int width, int hei //generate palette typedef struct { uint8_t r, g, b; } Color3; - Color3 table[256] = { {0} }; + Color3 table[256] = { { 0 } }; int tableIdx = 1; //we start counting at 1 because 0 is the transparent color //transparent is always last in the table tlb[tlbSize-1] = 0; @@ -550,7 +550,7 @@ static void msf_free_gif_state(MsfGifState * handle) { int msf_gif_begin(MsfGifState * handle, int width, int height) { MsfTimeFunc //NOTE: we cannot stomp the entire struct to zero because we must preserve `customAllocatorContext`. - MsfCookedFrame empty = {0}; //god I hate MSVC... + MsfCookedFrame empty = { 0 }; //god I hate MSVC... handle->previousFrame = empty; handle->currentFrame = empty; handle->width = width; @@ -614,7 +614,7 @@ int msf_gif_frame(MsfGifState * handle, uint8_t * pixelData, int centiSecondsPer } MsfGifResult msf_gif_end(MsfGifState * handle) { MsfTimeFunc - if (!handle->listHead) { MsfGifResult empty = {0}; return empty; } + if (!handle->listHead) { MsfGifResult empty = { 0 }; return empty; } //first pass: determine total size size_t total = 1; //1 byte for trailing marker diff --git a/examples/models/models_decals.c b/examples/models/models_decals.c index 71122dd68..9eba33de6 100644 --- a/examples/models/models_decals.c +++ b/examples/models/models_decals.c @@ -183,7 +183,7 @@ int main(void) if (showModel) DrawModel(model, (Vector3){0.0f, 0.0f, 0.0f}, 1.0f, WHITE); // Draw the decal models - for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){0}, 1.0f, WHITE); + for (int i = 0; i < decalCount; i++) DrawModel(decalModels[i], (Vector3){ 0 }, 1.0f, WHITE); // If we hit the mesh, draw the box for the decal if (collision.hit) @@ -191,7 +191,7 @@ int main(void) Vector3 origin = Vector3Add(collision.point, Vector3Scale(collision.normal, 1.0f)); Matrix splat = MatrixLookAt(collision.point, origin, (Vector3){0,1,0}); placementCube.transform = MatrixInvert(splat); - DrawModel(placementCube, (Vector3){0}, 1.0f, Fade(WHITE, 0.5f)); + DrawModel(placementCube, (Vector3){ 0 }, 1.0f, Fade(WHITE, 0.5f)); } DrawGrid(10, 10.0f); diff --git a/examples/models/models_rlgl_solar_system.c b/examples/models/models_rlgl_solar_system.c index d8d86d69a..0988ede8d 100644 --- a/examples/models/models_rlgl_solar_system.c +++ b/examples/models/models_rlgl_solar_system.c @@ -148,25 +148,25 @@ void DrawSphereBasic(Color color) { for (int j = 0; j < slices; j++) { - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*i)), - cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*(j*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*(j*360.0f/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*i))*sinf(DEG2RAD*(j*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*i)), - cosf(DEG2RAD*(270+(180/(rings + 1))*i))*cosf(DEG2RAD*(j*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360/slices))); - rlVertex3f(cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360/slices)), - sinf(DEG2RAD*(270+(180/(rings + 1))*(i+1))), - cosf(DEG2RAD*(270+(180/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*sinf(DEG2RAD*(j*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*i)), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*i))*cosf(DEG2RAD*(j*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*sinf(DEG2RAD*((j+1)*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i)))*cosf(DEG2RAD*((j+1)*360.0f/slices))); + rlVertex3f(cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*sinf(DEG2RAD*((j+1)*360.0f/slices)), + sinf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1))), + cosf(DEG2RAD*(270+(180.0f/(rings + 1))*(i+1)))*cosf(DEG2RAD*((j+1)*360.0f/slices))); } } rlEnd(); diff --git a/examples/models/models_waving_cubes.c b/examples/models/models_waving_cubes.c index 7996c1c8a..36e8bccf7 100644 --- a/examples/models/models_waving_cubes.c +++ b/examples/models/models_waving_cubes.c @@ -85,9 +85,9 @@ int main(void) // Calculate the cube position Vector3 cubePos = { - (float)(x - numBlocks/2)*(scale*3.0f) + scatter, - (float)(y - numBlocks/2)*(scale*2.0f) + scatter, - (float)(z - numBlocks/2)*(scale*3.0f) + scatter + (float)(x - (float)numBlocks/2)*(scale*3.0f) + scatter, + (float)(y - (float)numBlocks/2)*(scale*2.0f) + scatter, + (float)(z - (float)numBlocks/2)*(scale*3.0f) + scatter }; // Pick a color with a hue depending on cube position for the rainbow color effect diff --git a/examples/shaders/shaders_game_of_life.c b/examples/shaders/shaders_game_of_life.c index 9b9242a0d..0ae91b756 100644 --- a/examples/shaders/shaders_game_of_life.c +++ b/examples/shaders/shaders_game_of_life.c @@ -258,8 +258,8 @@ int main(void) UnloadImage(pattern); mode = MODE_PAUSE; - offsetX = worldWidth*presetPatterns[preset].position.x - windowWidth/zoom/2.0f; - offsetY = worldHeight*presetPatterns[preset].position.y - windowHeight/zoom/2.0f; + offsetX = worldWidth*presetPatterns[preset].position.x - (float)windowWidth/zoom/2.0f; + offsetY = worldHeight*presetPatterns[preset].position.y - (float)windowHeight/zoom/2.0f; } // Check window draw inside world limits diff --git a/examples/shaders/shaders_hybrid_rendering.c b/examples/shaders/shaders_hybrid_rendering.c index 439965fd6..ca6e93d9c 100644 --- a/examples/shaders/shaders_hybrid_rendering.c +++ b/examples/shaders/shaders_hybrid_rendering.c @@ -65,7 +65,7 @@ int main(void) Shader shdrRaster = LoadShader(0, TextFormat("resources/shaders/glsl%i/hybrid_raster.fs", GLSL_VERSION)); // Declare Struct used to store camera locs - RayLocs marchLocs = {0}; + RayLocs marchLocs = { 0 }; // Fill the struct with shader locs marchLocs.camPos = GetShaderLocation(shdrRaymarch, "camPos"); diff --git a/examples/shaders/shaders_vertex_displacement.c b/examples/shaders/shaders_vertex_displacement.c index 3eff34e00..8978b0fce 100644 --- a/examples/shaders/shaders_vertex_displacement.c +++ b/examples/shaders/shaders_vertex_displacement.c @@ -41,7 +41,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [shaders] example - vertex displacement"); // set up camera - Camera camera = {0}; + Camera camera = { 0 }; camera.position = (Vector3) {20.0f, 5.0f, -20.0f}; camera.target = (Vector3) {0.0f, 0.0f, 0.0f}; camera.up = (Vector3) {0.0f, 1.0f, 0.0f}; diff --git a/examples/shapes/shapes_ball_physics.c b/examples/shapes/shapes_ball_physics.c index 0c98ccf9d..293be1cd5 100644 --- a/examples/shapes/shapes_ball_physics.c +++ b/examples/shapes/shapes_ball_physics.c @@ -58,7 +58,7 @@ int main(void) 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 + Vector2 pressOffset = { 0 }; // Mouse press offset relative to the ball that grabbedd float gravity = 100; // World gravity diff --git a/examples/shapes/shapes_colors_palette.c b/examples/shapes/shapes_colors_palette.c index 9fbcf3063..44da323eb 100644 --- a/examples/shapes/shapes_colors_palette.c +++ b/examples/shapes/shapes_colors_palette.c @@ -45,7 +45,7 @@ int main(void) for (int i = 0; i < MAX_COLORS_COUNT; i++) { colorsRecs[i].x = 20.0f + 100.0f *(i%7) + 10.0f *(i%7); - colorsRecs[i].y = 80.0f + 100.0f *(i/7) + 10.0f *(i/7); + colorsRecs[i].y = 80.0f + 100.0f *((float)i/7) + 10.0f *((float)i/7); colorsRecs[i].width = 100.0f; colorsRecs[i].height = 100.0f; } diff --git a/examples/shapes/shapes_digital_clock.c b/examples/shapes/shapes_digital_clock.c index cca3f3c44..fb9ae80e6 100644 --- a/examples/shapes/shapes_digital_clock.c +++ b/examples/shapes/shapes_digital_clock.c @@ -311,7 +311,7 @@ static void DrawDisplaySegment(Vector2 center, int length, int thick, bool verti (Vector2){ center.x + thick/2.0f, center.y - length/2.0f }, // Point 3 (Vector2){ center.x - thick/2.0f, center.y + length/2.0f }, // Point 4 (Vector2){ center.x + thick/2.0f, center.y + length/2.0f }, // Point 5 - (Vector2){ center.x, center.y + length/2 + thick/2.0f }, // Point 6 + (Vector2){ center.x, center.y + (float)length/2 + thick/2.0f }, // Point 6 }; DrawTriangleStrip(segmentPointsV, 6, color); diff --git a/examples/shapes/shapes_double_pendulum.c b/examples/shapes/shapes_double_pendulum.c index 760d66203..5b357c9f3 100644 --- a/examples/shapes/shapes_double_pendulum.c +++ b/examples/shapes/shapes_double_pendulum.c @@ -49,8 +49,8 @@ int main(void) float totalM = m1 + m2; Vector2 previousPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2); - previousPosition.x += (screenWidth/2); - previousPosition.y += (screenHeight/2 - 100); + previousPosition.x += ((float)screenWidth/2); + previousPosition.y += ((float)screenHeight/2 - 100); // Scale length float L1 = l1*lengthScaler; @@ -105,8 +105,8 @@ int main(void) // Calculate position Vector2 currentPosition = CalculateDoublePendulumEndPoint(l1, theta1, l2, theta2); - currentPosition.x += screenWidth/2; - currentPosition.y += screenHeight/2 - 100; + currentPosition.x += (float)screenWidth/2; + currentPosition.y += (float)screenHeight/2 - 100; // Draw to render texture BeginTextureMode(target); diff --git a/examples/shapes/shapes_pie_chart.c b/examples/shapes/shapes_pie_chart.c index 6db7f96da..baf0a3652 100644 --- a/examples/shapes/shapes_pie_chart.c +++ b/examples/shapes/shapes_pie_chart.c @@ -49,8 +49,8 @@ int main(void) bool showPercentages = false; bool showDonut = false; int hoveredSlice = -1; - Rectangle scrollPanelBounds = {0}; - Vector2 scrollContentOffset = {0}; + Rectangle scrollPanelBounds = { 0 }; + Vector2 scrollContentOffset = { 0 }; Rectangle view = { 0 }; // UI layout parameters diff --git a/examples/text/text_3d_drawing.c b/examples/text/text_3d_drawing.c index 80b617b2e..aebf33837 100644 --- a/examples/text/text_3d_drawing.c +++ b/examples/text/text_3d_drawing.c @@ -113,7 +113,7 @@ int main(void) // Set the text (using markdown!) char text[64] = "Hello ~~World~~ in 3D!"; - Vector3 tbox = {0}; + Vector3 tbox = { 0 }; int layers = 1; int quads = 0; float layerDistance = 0.01f; @@ -133,7 +133,7 @@ int main(void) Shader alphaDiscard = LoadShader(NULL, TextFormat("resources/shaders/glsl%i/alpha_discard.fs", GLSL_VERSION)); // Array filled with multiple random colors (when multicolor mode is set) - Color multi[TEXT_MAX_LAYERS] = {0}; + Color multi[TEXT_MAX_LAYERS] = { 0 }; DisableCursor(); // Limit cursor to relative movement inside the window diff --git a/examples/text/text_font_sdf.c b/examples/text/text_font_sdf.c index 744450fa6..42b7495e2 100644 --- a/examples/text/text_font_sdf.c +++ b/examples/text/text_font_sdf.c @@ -97,8 +97,8 @@ int main(void) if (currentFont == 0) textSize = MeasureTextEx(fontDefault, msg, fontSize, 0); else textSize = MeasureTextEx(fontSDF, msg, fontSize, 0); - fontPosition.x = GetScreenWidth()/2 - textSize.x/2; - fontPosition.y = GetScreenHeight()/2 - textSize.y/2 + 80; + fontPosition.x = (float)GetScreenWidth()/2 - textSize.x/2; + fontPosition.y = (float)GetScreenHeight()/2 - textSize.y/2 + 80; //---------------------------------------------------------------------------------- // Draw diff --git a/examples/text/text_inline_styling.c b/examples/text/text_inline_styling.c index 81f8156b6..8634ccc19 100644 --- a/examples/text/text_inline_styling.c +++ b/examples/text/text_inline_styling.c @@ -180,12 +180,12 @@ static void DrawTextStyled(Font font, const char *text, Vector2 position, float if (text[i - 1] == 'c') { colFront = GetColor(colHexValue); - colFront.a = (unsigned char)(colFront.a * (float)color.a/255.0f); + //colFront.a *= (unsigned char)(colFront.a*(float)color.a/255.0f); // TODO: Review } else if (text[i - 1] == 'b') { colBack = GetColor(colHexValue); - colBack.a *= (unsigned char)(colFront.a * (float)color.a / 255.0f); + //colBack.a *= (unsigned char)(colFront.a*(float)color.a/255.0f); } i += (colHexCount + 1); // Skip color value retrieved and ']' diff --git a/examples/text/text_rectangle_bounds.c b/examples/text/text_rectangle_bounds.c index e180ae475..b87a3a956 100644 --- a/examples/text/text_rectangle_bounds.c +++ b/examples/text/text_rectangle_bounds.c @@ -226,7 +226,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } } @@ -234,7 +234,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } @@ -258,7 +258,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, if (wordWrap && (i == endLine)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; startLine = endLine; endLine = -1; diff --git a/examples/text/text_strings_management.c b/examples/text/text_strings_management.c index e4a7ab2af..db4540081 100644 --- a/examples/text/text_strings_management.c +++ b/examples/text/text_strings_management.c @@ -65,7 +65,7 @@ int main(void) TextParticle textParticles[MAX_TEXT_PARTICLES] = { 0 }; int particleCount = 0; TextParticle *grabbedTextParticle = NULL; - Vector2 pressOffset = {0}; + Vector2 pressOffset = { 0 }; PrepareFirstTextParticle("raylib => fun videogames programming!", textParticles, &particleCount); diff --git a/examples/text/text_unicode_emojis.c b/examples/text/text_unicode_emojis.c index 00712745d..240b50052 100644 --- a/examples/text/text_unicode_emojis.c +++ b/examples/text/text_unicode_emojis.c @@ -277,7 +277,7 @@ int main(void) DrawTriangle(a, b, c, emoji[selected].color); // Draw the main text message - Rectangle textRect = { msgRect.x + horizontalPadding/2, msgRect.y + verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height }; + Rectangle textRect = { msgRect.x + (float)horizontalPadding/2, msgRect.y + (float)verticalPadding/2, msgRect.width - horizontalPadding, msgRect.height }; DrawTextBoxed(*font, messages[message].text, textRect, (float)font->baseSize, 1.0f, true, WHITE); // Draw the info text below the main message @@ -421,7 +421,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } } @@ -429,7 +429,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, { if (!wordWrap && ((textOffsetX + glyphWidth) > rec.width)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; } @@ -453,7 +453,7 @@ static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, if (wordWrap && (i == endLine)) { - textOffsetY += (font.baseSize + font.baseSize/2)*scaleFactor; + textOffsetY += (font.baseSize + (float)font.baseSize/2)*scaleFactor; textOffsetX = 0; startLine = endLine; endLine = -1; diff --git a/examples/text/text_words_alignment.c b/examples/text/text_words_alignment.c index dbd9cd03e..f7ffa74af 100644 --- a/examples/text/text_words_alignment.c +++ b/examples/text/text_words_alignment.c @@ -41,7 +41,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [text] example - words alignment"); // Define the rectangle we will draw the text in - Rectangle textContainerRect = (Rectangle){ screenWidth/2-screenWidth/4, screenHeight/2-screenHeight/3, screenWidth/2, screenHeight*2/3 }; + Rectangle textContainerRect = (Rectangle){ (float)screenWidth/2-(float)screenWidth/4, (float)screenHeight/2-(float)screenHeight/3, (float)screenWidth/2, (float)screenHeight*2/3 }; // Some text to display the current alignment const char *textAlignNameH[] = { "Left", "Centre", "Right" }; diff --git a/examples/textures/textures_bunnymark.c b/examples/textures/textures_bunnymark.c index a95181ed6..3279abb8f 100644 --- a/examples/textures/textures_bunnymark.c +++ b/examples/textures/textures_bunnymark.c @@ -83,10 +83,10 @@ int main(void) bunnies[i].position.x += bunnies[i].speed.x; bunnies[i].position.y += bunnies[i].speed.y; - if (((bunnies[i].position.x + texBunny.width/2) > GetScreenWidth()) || - ((bunnies[i].position.x + texBunny.width/2) < 0)) bunnies[i].speed.x *= -1; - if (((bunnies[i].position.y + texBunny.height/2) > GetScreenHeight()) || - ((bunnies[i].position.y + texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1; + if (((bunnies[i].position.x + (float)texBunny.width/2) > GetScreenWidth()) || + ((bunnies[i].position.x + (float)texBunny.width/2) < 0)) bunnies[i].speed.x *= -1; + if (((bunnies[i].position.y + (float)texBunny.height/2) > GetScreenHeight()) || + ((bunnies[i].position.y + (float)texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1; } //---------------------------------------------------------------------------------- diff --git a/examples/textures/textures_cellular_automata.c b/examples/textures/textures_cellular_automata.c index affeeda93..802de3611 100644 --- a/examples/textures/textures_cellular_automata.c +++ b/examples/textures/textures_cellular_automata.c @@ -165,7 +165,7 @@ int main(void) // If the mouse is on this preset, highlight it if (mouseInCell == i + 8) - DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*(i/2), + DrawRectangleLinesEx((Rectangle) { 2 + (presetsSizeX + 2.0f)*((float)i/2), (presetsSizeY + 2.0f)*(i%2), presetsSizeX + 4.0f, presetsSizeY + 4.0f }, 3, RED); } diff --git a/examples/textures/textures_fog_of_war.c b/examples/textures/textures_fog_of_war.c index 4733caeb4..ea98b03ce 100644 --- a/examples/textures/textures_fog_of_war.c +++ b/examples/textures/textures_fog_of_war.c @@ -93,8 +93,8 @@ int main(void) for (unsigned int i = 0; i < map.tilesX*map.tilesY; i++) if (map.tileFog[i] == 1) map.tileFog[i] = 2; // Get current tile position from player pixel position - playerTileX = (int)((playerPosition.x + MAP_TILE_SIZE/2)/MAP_TILE_SIZE); - playerTileY = (int)((playerPosition.y + MAP_TILE_SIZE/2)/MAP_TILE_SIZE); + playerTileX = (int)((playerPosition.x + (float)MAP_TILE_SIZE/2)/MAP_TILE_SIZE); + playerTileY = (int)((playerPosition.y + (float)MAP_TILE_SIZE/2)/MAP_TILE_SIZE); // Check visibility and update fog // NOTE: We check tilemap limits to avoid processing tiles out-of-array-bounds (it could crash program) diff --git a/examples/textures/textures_image_processing.c b/examples/textures/textures_image_processing.c index 474974f97..8d2472c0a 100644 --- a/examples/textures/textures_image_processing.c +++ b/examples/textures/textures_image_processing.c @@ -156,7 +156,7 @@ int main(void) { DrawRectangleRec(toggleRecs[i], ((i == currentProcess) || (i == mouseHoverRec)) ? SKYBLUE : LIGHTGRAY); DrawRectangleLines((int)toggleRecs[i].x, (int) toggleRecs[i].y, (int) toggleRecs[i].width, (int) toggleRecs[i].height, ((i == currentProcess) || (i == mouseHoverRec)) ? BLUE : GRAY); - DrawText( processText[i], (int)( toggleRecs[i].x + toggleRecs[i].width/2 - MeasureText(processText[i], 10)/2), (int) toggleRecs[i].y + 11, 10, ((i == currentProcess) || (i == mouseHoverRec)) ? DARKBLUE : DARKGRAY); + DrawText( processText[i], (int)( toggleRecs[i].x + toggleRecs[i].width/2 - (float)MeasureText(processText[i], 10)/2), (int) toggleRecs[i].y + 11, 10, ((i == currentProcess) || (i == mouseHoverRec)) ? DARKBLUE : DARKGRAY); } DrawTexture(texture, screenWidth - texture.width - 60, screenHeight/2 - texture.height/2, WHITE); diff --git a/examples/textures/textures_image_text.c b/examples/textures/textures_image_text.c index e6777261a..b71ca4792 100644 --- a/examples/textures/textures_image_text.c +++ b/examples/textures/textures_image_text.c @@ -38,7 +38,7 @@ int main(void) Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM) UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM - Vector2 position = { (float)(screenWidth/2 - texture.width/2), (float)(screenHeight/2 - texture.height/2 - 20) }; + Vector2 position = { (float)screenWidth/2 - (float)texture.width/2, (float)screenHeight/2 - (float)texture.height/2 - 20 }; bool showFont = false; diff --git a/examples/textures/textures_sprite_button.c b/examples/textures/textures_sprite_button.c index a7db93c4f..7fe2adfd6 100644 --- a/examples/textures/textures_sprite_button.c +++ b/examples/textures/textures_sprite_button.c @@ -39,7 +39,7 @@ int main(void) Rectangle sourceRec = { 0, 0, (float)button.width, frameHeight }; // Define button bounds on screen - Rectangle btnBounds = { screenWidth/2.0f - button.width/2.0f, screenHeight/2.0f - button.height/NUM_FRAMES/2.0f, (float)button.width, frameHeight }; + Rectangle btnBounds = { screenWidth/2.0f - button.width/2.0f, screenHeight/2.0f - (float)button.height/NUM_FRAMES/2.0f, (float)button.width, frameHeight }; int btnState = 0; // Button state: 0-NORMAL, 1-MOUSE_HOVER, 2-PRESSED bool btnAction = false; // Button action should be activated diff --git a/examples/textures/textures_sprite_explosion.c b/examples/textures/textures_sprite_explosion.c index fe9669224..7efe8cf17 100644 --- a/examples/textures/textures_sprite_explosion.c +++ b/examples/textures/textures_sprite_explosion.c @@ -39,8 +39,8 @@ int main(void) Texture2D explosion = LoadTexture("resources/explosion.png"); // Init variables for animation - float frameWidth = (float)(explosion.width/NUM_FRAMES_PER_LINE); // Sprite one frame rectangle width - float frameHeight = (float)(explosion.height/NUM_LINES); // Sprite one frame rectangle height + float frameWidth = (float)explosion.width/NUM_FRAMES_PER_LINE; // Sprite one frame rectangle width + float frameHeight = (float)explosion.height/NUM_LINES; // Sprite one frame rectangle height int currentFrame = 0; int currentLine = 0; diff --git a/src/external/miniaudio.h b/src/external/miniaudio.h index b7e7a54dd..24e676bb2 100644 --- a/src/external/miniaudio.h +++ b/src/external/miniaudio.h @@ -1,6 +1,6 @@ /* Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file. -miniaudio - v0.11.23 - 2025-09-11 +miniaudio - v0.11.24 - 2026-01-17 David Reid - mackron@gmail.com @@ -3747,7 +3747,7 @@ extern "C" { #define MA_VERSION_MAJOR 0 #define MA_VERSION_MINOR 11 -#define MA_VERSION_REVISION 23 +#define MA_VERSION_REVISION 24 #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION) #if defined(_MSC_VER) && !defined(__clang__) @@ -3858,7 +3858,7 @@ typedef ma_uint16 wchar_t; /* Platform/backend detection. */ -#if defined(_WIN32) || defined(__COSMOPOLITAN__) +#if defined(_WIN32) #define MA_WIN32 #if defined(MA_FORCE_UWP) || (defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PC_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) || (defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP))) #define MA_WIN32_UWP @@ -4182,9 +4182,13 @@ typedef enum MA_CHANNEL_AUX_29 = 49, MA_CHANNEL_AUX_30 = 50, MA_CHANNEL_AUX_31 = 51, + + /* Count. */ + MA_CHANNEL_POSITION_COUNT, + + /* Aliases. */ MA_CHANNEL_LEFT = MA_CHANNEL_FRONT_LEFT, MA_CHANNEL_RIGHT = MA_CHANNEL_FRONT_RIGHT, - MA_CHANNEL_POSITION_COUNT = (MA_CHANNEL_AUX_31 + 1) } _ma_channel_position; /* Do not use `_ma_channel_position` directly. Use `ma_channel` instead. */ typedef enum @@ -6604,16 +6608,12 @@ This section contains the APIs for device playback and capture. Here is where yo #if defined(MA_WIN32_DESKTOP) /* DirectSound and WinMM backends are only supported on desktops. */ #define MA_SUPPORT_DSOUND #define MA_SUPPORT_WINMM - - /* Don't enable JACK here if compiling with Cosmopolitan. It'll be enabled in the Linux section below. */ - #if !defined(__COSMOPOLITAN__) - #define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */ - #endif + #define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */ #endif #endif #if defined(MA_UNIX) && !defined(MA_ORBIS) && !defined(MA_PROSPERO) #if defined(MA_LINUX) - #if !defined(MA_ANDROID) && !defined(__COSMOPOLITAN__) /* ALSA is not supported on Android. */ + #if !defined(MA_ANDROID) && !defined(MA_EMSCRIPTEN) /* ALSA is not supported on Android. */ #define MA_SUPPORT_ALSA #endif #endif @@ -9675,7 +9675,7 @@ Parameters ---------- pBackends (out, optional) A pointer to the buffer that will receive the enabled backends. Set to NULL to retrieve the backend count. Setting - the capacity of the buffer to `MA_BUFFER_COUNT` will guarantee it's large enough for all backends. + the capacity of the buffer to `MA_BACKEND_COUNT` will guarantee it's large enough for all backends. backendCap (in) The capacity of the `pBackends` buffer. @@ -10520,6 +10520,7 @@ typedef struct ma_decoding_backend_vtable** ppCustomDecodingBackendVTables; ma_uint32 customDecodingBackendCount; void* pCustomDecodingBackendUserData; + ma_resampler_config resampling; } ma_resource_manager_config; MA_API ma_resource_manager_config ma_resource_manager_config_init(void); @@ -10847,6 +10848,7 @@ MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void* MA_API ma_uint32 ma_node_graph_get_channels(const ma_node_graph* pNodeGraph); MA_API ma_uint64 ma_node_graph_get_time(const ma_node_graph* pNodeGraph); MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 globalTime); +MA_API ma_uint32 ma_node_graph_get_processing_size_in_frames(const ma_node_graph* pNodeGraph); @@ -11154,6 +11156,7 @@ typedef struct ma_bool8 isPitchDisabled; /* Pitching can be explicitly disabled with MA_SOUND_FLAG_NO_PITCH to optimize processing. */ ma_bool8 isSpatializationDisabled; /* Spatialization can be explicitly disabled with MA_SOUND_FLAG_NO_SPATIALIZATION. */ ma_uint8 pinnedListenerIndex; /* The index of the listener this node should always use for spatialization. If set to MA_LISTENER_INDEX_CLOSEST the engine will use the closest listener. */ + ma_resampler_config resampling; } ma_engine_node_config; MA_API ma_engine_node_config ma_engine_node_config_init(ma_engine* pEngine, ma_engine_node_type type, ma_uint32 flags); @@ -11168,7 +11171,7 @@ typedef struct ma_uint32 volumeSmoothTimeInPCMFrames; ma_mono_expansion_mode monoExpansionMode; ma_fader fader; - ma_linear_resampler resampler; /* For pitch shift. */ + ma_resampler resampler; /* For pitch shift. */ ma_spatializer spatializer; ma_panner panner; ma_gainer volumeGainer; /* This will only be used if volumeSmoothTimeInPCMFrames is > 0. */ @@ -11224,6 +11227,7 @@ typedef struct ma_uint64 loopPointEndInPCMFrames; ma_sound_end_proc endCallback; /* Fired when the sound reaches the end. Will be fired from the audio thread. Do not restart, uninitialize or otherwise change the state of the sound from here. Instead fire an event or set a variable to indicate to a different thread to change the start of the sound. Will not be fired in response to a scheduled stop with ma_sound_set_stop_time_*(). */ void* pEndCallbackUserData; + ma_resampler_config pitchResampling; #ifndef MA_NO_RESOURCE_MANAGER ma_resource_manager_pipeline_notifications initNotifications; #endif @@ -11242,7 +11246,10 @@ struct ma_sound MA_ATOMIC(4, ma_bool32) atEnd; ma_sound_end_proc endCallback; void* pEndCallbackUserData; - ma_bool8 ownsDataSource; + float* pProcessingCache; /* Will be null if pDataSource is null. */ + ma_uint32 processingCacheFramesRemaining; + ma_uint32 processingCacheCap; + ma_bool8 ownsDataSource; /* We're declaring a resource manager data source object here to save us a malloc when loading a @@ -11300,6 +11307,8 @@ typedef struct ma_vfs* pResourceManagerVFS; /* A pointer to a pre-allocated VFS object to use with the resource manager. This is ignored if pResourceManager is not NULL. */ ma_engine_process_proc onProcess; /* Fired at the end of each call to ma_engine_read_pcm_frames(). For engine's that manage their own internal device (the default configuration), this will be fired from the audio thread, and you do not need to call ma_engine_read_pcm_frames() manually in order to trigger this. */ void* pProcessUserData; /* User data that's passed into onProcess. */ + ma_resampler_config resourceManagerResampling; /* The resampling config to use with the resource manager. */ + ma_resampler_config pitchResampling; /* The resampling config for the pitch and Doppler effects. You will typically want this to be a fast resampler. For high quality stuff, it's recommended that you pre-resample. */ } ma_engine_config; MA_API ma_engine_config ma_engine_config_init(void); @@ -11329,6 +11338,7 @@ struct ma_engine ma_mono_expansion_mode monoExpansionMode; ma_engine_process_proc onProcess; void* pProcessUserData; + ma_resampler_config pitchResamplingConfig; }; MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEngine); @@ -11389,8 +11399,12 @@ MA_API ma_engine* ma_sound_get_engine(const ma_sound* pSound); MA_API ma_data_source* ma_sound_get_data_source(const ma_sound* pSound); MA_API ma_result ma_sound_start(ma_sound* pSound); MA_API ma_result ma_sound_stop(ma_sound* pSound); -MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. */ -MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. */ +MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. If you want to restart the sound, first reset it with `ma_sound_reset_stop_time_and_fade()`. There are plans to make this less awkward in the future. */ +MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 fadeLengthInFrames); /* Will overwrite any scheduled stop and fade. If you want to restart the sound, first reset it with `ma_sound_reset_stop_time_and_fade()`. There are plans to make this less awkward in the future. */ +MA_API void ma_sound_reset_start_time(ma_sound* pSound); +MA_API void ma_sound_reset_stop_time(ma_sound* pSound); +MA_API void ma_sound_reset_fade(ma_sound* pSound); +MA_API void ma_sound_reset_stop_time_and_fade(ma_sound* pSound); /* Resets fades and scheduled stop time. Does not seek back to the start. */ MA_API void ma_sound_set_volume(ma_sound* pSound, float volume); MA_API float ma_sound_get_volume(const ma_sound* pSound); MA_API void ma_sound_set_pan(ma_sound* pSound, float pan); @@ -11643,7 +11657,7 @@ IMPLEMENTATION #endif /* Intrinsics Support */ -#if (defined(MA_X64) || defined(MA_X86)) && !defined(__COSMOPOLITAN__) +#if defined(MA_X64) || defined(MA_X86) #if defined(_MSC_VER) && !defined(__clang__) /* MSVC. */ #if _MSC_VER >= 1400 && !defined(MA_NO_SSE2) /* 2005 */ @@ -12080,7 +12094,7 @@ static MA_INLINE unsigned int ma_disable_denormals(void) } #elif defined(MA_X86) || defined(MA_X64) { - #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ + #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ { prevState = _mm_getcsr(); _mm_setcsr(prevState | MA_MM_DENORMALS_ZERO_MASK | MA_MM_FLUSH_ZERO_MASK); @@ -12120,7 +12134,7 @@ static MA_INLINE void ma_restore_denormals(unsigned int prevState) } #elif defined(MA_X86) || defined(MA_X64) { - #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__) || defined(__COSMOPOLITAN__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ + #if defined(MA_SUPPORT_SSE2) && defined(__SSE2__) && !(defined(__TINYC__) || defined(__WATCOMC__)) /* <-- Add compilers that lack support for _mm_getcsr() and _mm_setcsr() to this list. */ { _mm_setcsr(prevState); } @@ -14241,6 +14255,29 @@ typedef int ma_atomic_memory_order; #define ma_atomic_memory_order_release 4 #define ma_atomic_memory_order_acq_rel 5 #define ma_atomic_memory_order_seq_cst 6 + #define MA_ATOMIC_MSVC_ARM_INTRINSIC_NORETURN(dst, src, order, intrin, ma_atomicType, msvcType) \ + switch (order) \ + { \ + case ma_atomic_memory_order_relaxed: \ + { \ + intrin##_nf((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case ma_atomic_memory_order_consume: \ + case ma_atomic_memory_order_acquire: \ + { \ + intrin##_acq((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case ma_atomic_memory_order_release: \ + { \ + intrin##_rel((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + case ma_atomic_memory_order_acq_rel: \ + case ma_atomic_memory_order_seq_cst: \ + default: \ + { \ + intrin((volatile msvcType*)dst, (msvcType)src); \ + } break; \ + } #define MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, src, order, intrin, ma_atomicType, msvcType) \ ma_atomicType result; \ switch (order) \ @@ -14284,7 +14321,7 @@ typedef int ma_atomic_memory_order; { #if defined(MA_ARM) { - MA_ATOMIC_MSVC_ARM_INTRINSIC(dst, 0, order, _InterlockedExchange, ma_atomic_flag, long); + MA_ATOMIC_MSVC_ARM_INTRINSIC_NORETURN(dst, 0, order, _InterlockedExchange, ma_atomic_flag, long); } #else { @@ -17593,7 +17630,7 @@ static ma_result ma_thread_create__posix(ma_thread* pThread, ma_thread_priority int priorityStep = (priorityMax - priorityMin) / 7; /* 7 = number of priorities supported by miniaudio. */ struct sched_param sched; - if (pthread_attr_getschedparam(&attr, &sched) == 0) { + if (priorityMin != -1 && priorityMax != -1 && pthread_attr_getschedparam(&attr, &sched) == 0) { if (priority == ma_thread_priority_idle) { sched.sched_priority = priorityMin; } else if (priority == ma_thread_priority_realtime) { @@ -20050,7 +20087,7 @@ Timing struct timespec newTime; clock_gettime(MA_CLOCK_ID, &newTime); - pTimer->counter = (newTime.tv_sec * 1000000000) + newTime.tv_nsec; + pTimer->counter = ((ma_int64)newTime.tv_sec * 1000000000) + newTime.tv_nsec; } static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer) @@ -20061,7 +20098,7 @@ Timing struct timespec newTime; clock_gettime(MA_CLOCK_ID, &newTime); - newTimeCounter = (newTime.tv_sec * 1000000000) + newTime.tv_nsec; + newTimeCounter = ((ma_uint64)newTime.tv_sec * 1000000000) + newTime.tv_nsec; oldTimeCounter = pTimer->counter; return (newTimeCounter - oldTimeCounter) / 1000000000.0; @@ -20072,7 +20109,7 @@ Timing struct timeval newTime; gettimeofday(&newTime, NULL); - pTimer->counter = (newTime.tv_sec * 1000000) + newTime.tv_usec; + pTimer->counter = ((ma_int64)newTime.tv_sec * 1000000) + newTime.tv_usec; } static MA_INLINE double ma_timer_get_time_in_seconds(ma_timer* pTimer) @@ -20083,7 +20120,7 @@ Timing struct timeval newTime; gettimeofday(&newTime, NULL); - newTimeCounter = (newTime.tv_sec * 1000000) + newTime.tv_usec; + newTimeCounter = ((ma_uint64)newTime.tv_sec * 1000000) + newTime.tv_usec; oldTimeCounter = pTimer->counter; return (newTimeCounter - oldTimeCounter) / 1000000.0; @@ -31205,6 +31242,7 @@ static ma_result ma_init_pa_mainloop_and_pa_context__pulse(ma_context* pContext, result = ma_result_from_pulse(((ma_pa_context_connect_proc)pContext->pulse.pa_context_connect)((ma_pa_context*)pPulseContext, pServerName, (tryAutoSpawn) ? MA_PA_CONTEXT_NOFLAGS : MA_PA_CONTEXT_NOAUTOSPAWN, NULL)); if (result != MA_SUCCESS) { ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to connect PulseAudio context."); + ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)(pPulseContext)); ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)((ma_pa_mainloop*)(pMainLoop)); return result; } @@ -31213,6 +31251,7 @@ static ma_result ma_init_pa_mainloop_and_pa_context__pulse(ma_context* pContext, result = ma_wait_for_pa_context_to_connect__pulse(pContext, pMainLoop, pPulseContext); if (result != MA_SUCCESS) { ma_log_postf(ma_context_get_log(pContext), MA_LOG_LEVEL_ERROR, "[PulseAudio] Waiting for connection failed."); + ((ma_pa_context_unref_proc)pContext->pulse.pa_context_unref)((ma_pa_context*)(pPulseContext)); ((ma_pa_mainloop_free_proc)pContext->pulse.pa_mainloop_free)((ma_pa_mainloop*)(pMainLoop)); return result; } @@ -41724,8 +41763,11 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const frameCount = pDevice->capture.internalPeriodSizeInFrames; } + /* + If this is called by the device has not yet been started we need to return early, making sure we output silence to + the output buffer. + */ if (ma_device_get_state(pDevice) != ma_device_state_started) { - /* Fill the output buffer with zero to avoid a noise sound */ for (int i = 0; i < outputCount; i += 1) { MA_ZERO_MEMORY(pOutputs[i].data, pOutputs[i].numberOfChannels * frameCount * sizeof(float)); } @@ -41747,7 +41789,9 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const if (outputCount > 0) { /* If it's a capture-only device, we'll need to output silence. */ if (pDevice->type == ma_device_type_capture) { - MA_ZERO_MEMORY(pOutputs[0].data, frameCount * pDevice->playback.internalChannels * sizeof(float)); + for (int i = 0; i < outputCount; i += 1) { + MA_ZERO_MEMORY(pOutputs[i].data, pOutputs[i].numberOfChannels * frameCount * sizeof(float)); + } } else { ma_device_process_pcm_frames_playback__webaudio(pDevice, frameCount, pDevice->webaudio.pIntermediaryBuffer); @@ -41757,6 +41801,14 @@ static EM_BOOL ma_audio_worklet_process_callback__webaudio(int inputCount, const pOutputs[0].data[frameCount*iChannel + iFrame] = pDevice->webaudio.pIntermediaryBuffer[iFrame*pDevice->playback.internalChannels + iChannel]; } } + + /* + Just above we output data to the first output buffer. Here we just make sure we're putting silence into any + remaining output buffers. + */ + for (int i = 1; i < outputCount; i += 1) { /* <-- Note that the counter starts at 1 instead of 0. */ + MA_ZERO_MEMORY(pOutputs[i].data, pOutputs[i].numberOfChannels * frameCount * sizeof(float)); + } } } @@ -42237,8 +42289,8 @@ static ma_result ma_context_uninit__webaudio(ma_context* pContext) /* Remove the global miniaudio object from window if there are no more references to it. */ EM_ASM({ if (typeof(window.miniaudio) !== 'undefined') { - miniaudio.unlock_event_types.map(function(event_type) { - document.removeEventListener(event_type, miniaudio.unlock, true); + window.miniaudio.unlock_event_types.map(function(event_type) { + document.removeEventListener(event_type, window.miniaudio.unlock, true); }); window.miniaudio.referenceCount -= 1; @@ -50827,15 +50879,15 @@ static /*__attribute__((noinline))*/ ma_result ma_gainer_process_pcm_frames_inte a += d; } } + + pFramesOut = ma_offset_ptr(pFramesOut, interpolatedFrameCount * sizeof(float)); + pFramesIn = ma_offset_ptr(pFramesIn, interpolatedFrameCount * sizeof(float)); } + frameCount -= interpolatedFrameCount; + /* Make sure the timer is updated. */ pGainer->t = (ma_uint32)ma_min(pGainer->t + interpolatedFrameCount, pGainer->config.smoothTimeInFrames); - - /* Adjust our arguments so the next part can work normally. */ - frameCount -= interpolatedFrameCount; - pFramesOut = ma_offset_ptr(pFramesOut, interpolatedFrameCount * sizeof(float)); - pFramesIn = ma_offset_ptr(pFramesIn, interpolatedFrameCount * sizeof(float)); } /* All we need to do here is apply the new gains using an optimized path. */ @@ -52263,13 +52315,16 @@ static float ma_calculate_angular_gain(ma_vec3f dirA, ma_vec3f dirB, float coneI MA_API ma_result ma_spatializer_process_pcm_frames(ma_spatializer* pSpatializer, ma_spatializer_listener* pListener, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount) { - ma_channel* pChannelMapIn = pSpatializer->pChannelMapIn; - ma_channel* pChannelMapOut = pListener->config.pChannelMapOut; + ma_channel* pChannelMapIn; + ma_channel* pChannelMapOut; - if (pSpatializer == NULL) { + if (pSpatializer == NULL || pListener == NULL) { return MA_INVALID_ARGS; } + pChannelMapIn = pSpatializer->pChannelMapIn; + pChannelMapOut = pListener->config.pChannelMapOut; + /* If we're not spatializing we need to run an optimized path. */ if (ma_atomic_load_i32(&pSpatializer->attenuationModel) == ma_attenuation_model_none) { if (ma_spatializer_listener_is_enabled(pListener)) { @@ -52314,23 +52369,17 @@ MA_API ma_result ma_spatializer_process_pcm_frames(ma_spatializer* pSpatializer, We'll need the listener velocity for doppler pitch calculations. The speed of sound is defined by the listener, so we'll grab that here too. */ - if (pListener != NULL) { - listenerVel = ma_spatializer_listener_get_velocity(pListener); - speedOfSound = pListener->config.speedOfSound; - } else { - listenerVel = ma_vec3f_init_3f(0, 0, 0); - speedOfSound = MA_DEFAULT_SPEED_OF_SOUND; - } + listenerVel = ma_spatializer_listener_get_velocity(pListener); + speedOfSound = pListener->config.speedOfSound; - if (pListener == NULL || ma_spatializer_get_positioning(pSpatializer) == ma_positioning_relative) { - /* There's no listener or we're using relative positioning. */ + if (ma_spatializer_get_positioning(pSpatializer) == ma_positioning_relative) { relativePos = ma_spatializer_get_position(pSpatializer); relativeDir = ma_spatializer_get_direction(pSpatializer); } else { /* - We've found a listener and we're using absolute positioning. We need to transform the - sound's position and direction so that it's relative to listener. Later on we'll use - this for determining the factors to apply to each channel to apply the panning effect. + We're using absolute positioning. We need to transform the sound's position and + direction so that it's relative to listener. Later on we'll use this for determining + the factors to apply to each channel to apply the panning effect. */ ma_spatializer_get_relative_position_and_direction(pSpatializer, pListener, &relativePos, &relativeDir); } @@ -54365,7 +54414,7 @@ static ma_bool32 ma_is_spatial_channel_position(ma_channel channelPosition) return MA_FALSE; } - if (channelPosition >= MA_CHANNEL_AUX_0 && channelPosition <= MA_CHANNEL_AUX_31) { + if (channelPosition >= MA_CHANNEL_AUX_0) { return MA_FALSE; } @@ -61653,7 +61702,6 @@ static ma_result ma_default_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_inf if (result == MA_NOT_IMPLEMENTED) { /* Not implemented. Fall back to seek/tell/seek. */ - ma_result result; ma_int64 cursor; ma_int64 sizeInBytes; @@ -61861,6 +61909,8 @@ Decoding and Encoding Headers. These are auto-generated from a tool. **************************************************************************************************************************************************************/ #if !defined(MA_NO_WAV) && (!defined(MA_NO_DECODING) || !defined(MA_NO_ENCODING)) +#define MA_HAS_WAV + /* dr_wav_h begin */ #ifndef ma_dr_wav_h #define ma_dr_wav_h @@ -61871,7 +61921,7 @@ extern "C" { #define MA_DR_WAV_XSTRINGIFY(x) MA_DR_WAV_STRINGIFY(x) #define MA_DR_WAV_VERSION_MAJOR 0 #define MA_DR_WAV_VERSION_MINOR 14 -#define MA_DR_WAV_VERSION_REVISION 1 +#define MA_DR_WAV_VERSION_REVISION 4 #define MA_DR_WAV_VERSION_STRING MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MAJOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_MINOR) "." MA_DR_WAV_XSTRINGIFY(MA_DR_WAV_VERSION_REVISION) #include #define MA_DR_WAVE_FORMAT_PCM 0x1 @@ -62294,6 +62344,8 @@ MA_API ma_bool32 ma_dr_wav_fourcc_equal(const ma_uint8* a, const char* b); #endif /* MA_NO_WAV */ #if !defined(MA_NO_FLAC) && !defined(MA_NO_DECODING) +#define MA_HAS_FLAC + /* dr_flac_h begin */ #ifndef ma_dr_flac_h #define ma_dr_flac_h @@ -62304,7 +62356,7 @@ extern "C" { #define MA_DR_FLAC_XSTRINGIFY(x) MA_DR_FLAC_STRINGIFY(x) #define MA_DR_FLAC_VERSION_MAJOR 0 #define MA_DR_FLAC_VERSION_MINOR 13 -#define MA_DR_FLAC_VERSION_REVISION 1 +#define MA_DR_FLAC_VERSION_REVISION 3 #define MA_DR_FLAC_VERSION_STRING MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MAJOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_MINOR) "." MA_DR_FLAC_XSTRINGIFY(MA_DR_FLAC_VERSION_REVISION) #include #if defined(_MSC_VER) && _MSC_VER >= 1700 @@ -62392,8 +62444,9 @@ typedef struct typedef struct { ma_uint32 type; - const void* pRawData; ma_uint32 rawDataSize; + ma_uint64 rawDataOffset; + const void* pRawData; union { ma_dr_flac_streaminfo streaminfo; @@ -62439,6 +62492,7 @@ typedef struct ma_uint32 colorDepth; ma_uint32 indexColorCount; ma_uint32 pictureDataSize; + ma_uint64 pictureDataOffset; const ma_uint8* pPictureData; } picture; } data; @@ -62584,6 +62638,8 @@ MA_API ma_bool32 ma_dr_flac_next_cuesheet_track(ma_dr_flac_cuesheet_track_iterat #endif /* MA_NO_FLAC */ #if !defined(MA_NO_MP3) && !defined(MA_NO_DECODING) +#define MA_HAS_MP3 + #ifndef MA_DR_MP3_NO_SIMD #if (defined(MA_NO_NEON) && defined(MA_ARM)) || (defined(MA_NO_SSE2) && (defined(MA_X86) || defined(MA_X64))) #define MA_DR_MP3_NO_SIMD @@ -62600,22 +62656,47 @@ extern "C" { #define MA_DR_MP3_XSTRINGIFY(x) MA_DR_MP3_STRINGIFY(x) #define MA_DR_MP3_VERSION_MAJOR 0 #define MA_DR_MP3_VERSION_MINOR 7 -#define MA_DR_MP3_VERSION_REVISION 1 +#define MA_DR_MP3_VERSION_REVISION 3 #define MA_DR_MP3_VERSION_STRING MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MAJOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_MINOR) "." MA_DR_MP3_XSTRINGIFY(MA_DR_MP3_VERSION_REVISION) #include #define MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME 1152 #define MA_DR_MP3_MAX_SAMPLES_PER_FRAME (MA_DR_MP3_MAX_PCM_FRAMES_PER_MP3_FRAME*2) MA_API void ma_dr_mp3_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision); MA_API const char* ma_dr_mp3_version_string(void); +#define MA_DR_MP3_MAX_BITRESERVOIR_BYTES 511 +#define MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 +#define MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE typedef struct { int frame_bytes, channels, sample_rate, layer, bitrate_kbps; } ma_dr_mp3dec_frame_info; typedef struct +{ + const ma_uint8 *buf; + int pos, limit; +} ma_dr_mp3_bs; +typedef struct +{ + const ma_uint8 *sfbtab; + ma_uint16 part_23_length, big_values, scalefac_compress; + ma_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; + ma_uint8 table_select[3], region_count[3], subblock_gain[3]; + ma_uint8 preflag, scalefac_scale, count1_table, scfsi; +} ma_dr_mp3_L3_gr_info; +typedef struct +{ + ma_dr_mp3_bs bs; + ma_uint8 maindata[MA_DR_MP3_MAX_BITRESERVOIR_BYTES + MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES]; + ma_dr_mp3_L3_gr_info gr_info[4]; + float grbuf[2][576], scf[40], syn[18 + 15][2*32]; + ma_uint8 ist_pos[2][39]; +} ma_dr_mp3dec_scratch; +typedef struct { float mdct_overlap[2][9*32], qmf_state[15*2*32]; int reserv, free_format_bytes; ma_uint8 header[4], reserv_buf[511]; + ma_dr_mp3dec_scratch scratch; } ma_dr_mp3dec; MA_API void ma_dr_mp3dec_init(ma_dr_mp3dec *dec); MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int mp3_bytes, void *pcm, ma_dr_mp3dec_frame_info *info); @@ -63179,7 +63260,6 @@ static ma_result ma_decoder_init_custom_from_memory__internal(const void* pData, /* WAV */ #ifdef ma_dr_wav_h -#define MA_HAS_WAV typedef struct { @@ -63885,7 +63965,6 @@ static ma_result ma_decoder_init_wav_from_memory__internal(const void* pData, si /* FLAC */ #ifdef ma_dr_flac_h -#define MA_HAS_FLAC typedef struct { @@ -64529,7 +64608,6 @@ static ma_result ma_decoder_init_flac_from_memory__internal(const void* pData, s /* MP3 */ #ifdef ma_dr_mp3_h -#define MA_HAS_MP3 typedef struct { @@ -66207,11 +66285,9 @@ static ma_result ma_decoder_init__internal(ma_decoder_read_proc onRead, ma_decod We use trial and error to open a decoder. We prioritize custom decoders so that if they implement the same encoding format they take priority over the built-in decoders. */ + result = ma_decoder_init_custom__internal(pConfig, pDecoder); if (result != MA_SUCCESS) { - result = ma_decoder_init_custom__internal(pConfig, pDecoder); - if (result != MA_SUCCESS) { - onSeek(pDecoder, 0, ma_seek_origin_start); - } + onSeek(pDecoder, 0, ma_seek_origin_start); } /* @@ -66475,14 +66551,6 @@ MA_API ma_result ma_decoder_init_memory(const void* pData, size_t dataSize, cons /* Initialization was successful. Finish up. */ result = ma_decoder__postinit(&config, pDecoder); if (result != MA_SUCCESS) { - /* - The backend was initialized successfully, but for some reason post-initialization failed. This is most likely - due to an out of memory error. We're going to abort with an error here and not try to recover. - */ - if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) { - pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks); - } - return result; } } else { @@ -66783,11 +66851,9 @@ MA_API ma_result ma_decoder_init_vfs(ma_vfs* pVFS, const char* pFilePath, const We use trial and error to open a decoder. We prioritize custom decoders so that if they implement the same encoding format they take priority over the built-in decoders. */ + result = ma_decoder_init_custom__internal(&config, pDecoder); if (result != MA_SUCCESS) { - result = ma_decoder_init_custom__internal(&config, pDecoder); - if (result != MA_SUCCESS) { - ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); - } + ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); } /* @@ -66916,11 +66982,9 @@ MA_API ma_result ma_decoder_init_vfs_w(ma_vfs* pVFS, const wchar_t* pFilePath, c We use trial and error to open a decoder. We prioritize custom decoders so that if they implement the same encoding format they take priority over the built-in decoders. */ + result = ma_decoder_init_custom__internal(&config, pDecoder); if (result != MA_SUCCESS) { - result = ma_decoder_init_custom__internal(&config, pDecoder); - if (result != MA_SUCCESS) { - ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); - } + ma_decoder__on_seek_vfs(pDecoder, 0, ma_seek_origin_start); } /* @@ -67102,14 +67166,6 @@ MA_API ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_co /* Initialization was successful. Finish up. */ result = ma_decoder__postinit(&config, pDecoder); if (result != MA_SUCCESS) { - /* - The backend was initialized successfully, but for some reason post-initialization failed. This is most likely - due to an out of memory error. We're going to abort with an error here and not try to recover. - */ - if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) { - pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks); - } - return result; } } else { @@ -67252,14 +67308,6 @@ MA_API ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decod /* Initialization was successful. Finish up. */ result = ma_decoder__postinit(&config, pDecoder); if (result != MA_SUCCESS) { - /* - The backend was initialized successfully, but for some reason post-initialization failed. This is most likely - due to an out of memory error. We're going to abort with an error here and not try to recover. - */ - if (pDecoder->pBackendVTable != NULL && pDecoder->pBackendVTable->onUninit != NULL) { - pDecoder->pBackendVTable->onUninit(pDecoder->pBackendUserData, &pDecoder->pBackend, &pDecoder->allocationCallbacks); - } - return result; } } else { @@ -69905,6 +69953,7 @@ MA_API ma_resource_manager_config ma_resource_manager_config_init(void) config.decodedSampleRate = 0; config.jobThreadCount = 1; /* A single miniaudio-managed job thread by default. */ config.jobQueueCapacity = MA_JOB_TYPE_RESOURCE_MANAGER_QUEUE_CAPACITY; + config.resampling = ma_resampler_config_init(ma_format_unknown, 0, 0, 0, ma_resample_algorithm_linear); /* Format/channels/rate doesn't matter here. */ /* Flags. */ config.flags = 0; @@ -70158,6 +70207,7 @@ static ma_decoder_config ma_resource_manager__init_decoder_config(ma_resource_ma config.ppCustomBackendVTables = pResourceManager->config.ppCustomDecodingBackendVTables; config.customBackendCount = pResourceManager->config.customDecodingBackendCount; config.pCustomBackendUserData = pResourceManager->config.pCustomDecodingBackendUserData; + config.resampling = pResourceManager->config.resampling; return config; } @@ -71483,13 +71533,13 @@ MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_man MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor) { - /* We cannot be using the data source after it's been uninitialized. */ - MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); - if (pDataBuffer == NULL || pCursor == NULL) { return MA_INVALID_ARGS; } + /* We cannot be using the data source after it's been uninitialized. */ + MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); + *pCursor = 0; switch (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode)) @@ -71523,13 +71573,13 @@ MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_res MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength) { - /* We cannot be using the data source after it's been uninitialized. */ - MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); - if (pDataBuffer == NULL || pLength == NULL) { return MA_INVALID_ARGS; } + /* We cannot be using the data source after it's been uninitialized. */ + MA_ASSERT(ma_resource_manager_data_buffer_node_result(pDataBuffer->pNode) != MA_UNAVAILABLE); + if (ma_resource_manager_data_buffer_node_get_data_supply_type(pDataBuffer->pNode) == ma_resource_manager_data_supply_type_unknown) { return MA_BUSY; /* Still loading. */ } @@ -72884,8 +72934,6 @@ static ma_result ma_job_process__resource_manager__free_data_buffer_node(ma_job* return ma_resource_manager_post_job(pResourceManager, pJob); /* Out of order. */ } - ma_resource_manager_data_buffer_node_free(pResourceManager, pDataBufferNode); - /* The event needs to be signalled last. */ if (pJob->data.resourceManager.freeDataBufferNode.pDoneNotification != NULL) { ma_async_notification_signal(pJob->data.resourceManager.freeDataBufferNode.pDoneNotification); @@ -72896,6 +72944,9 @@ static ma_result ma_job_process__resource_manager__free_data_buffer_node(ma_job* } ma_atomic_fetch_add_32(&pDataBufferNode->executionPointer, 1); + + ma_resource_manager_data_buffer_node_free(pResourceManager, pDataBufferNode); + return MA_SUCCESS; } @@ -73768,6 +73819,15 @@ MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 glo return ma_node_set_time(&pNodeGraph->endpoint, globalTime); /* Global time is just the local time of the endpoint. */ } +MA_API ma_uint32 ma_node_graph_get_processing_size_in_frames(const ma_node_graph* pNodeGraph) +{ + if (pNodeGraph == NULL) { + return 0; + } + + return pNodeGraph->processingSizeInFrames; +} + #define MA_NODE_OUTPUT_BUS_FLAG_HAS_READ 0x01 /* Whether or not this bus ready to read more data. Only used on nodes with multiple output buses. */ @@ -74927,12 +74987,12 @@ MA_API ma_node_state ma_node_get_state_by_time_range(const ma_node* pNode, ma_ui its start time not having been reached yet. Also, the stop time may have also been reached in which case it'll be considered stopped. */ - if (ma_node_get_state_time(pNode, ma_node_state_started) > globalTimeBeg) { - return ma_node_state_stopped; /* Start time has not yet been reached. */ + if (ma_node_get_state_time(pNode, ma_node_state_stopped) < globalTimeBeg) { + return ma_node_state_stopped; /* End time is before the start of the range. */ } - if (ma_node_get_state_time(pNode, ma_node_state_stopped) <= globalTimeEnd) { - return ma_node_state_stopped; /* Stop time has been reached. */ + if (ma_node_get_state_time(pNode, ma_node_state_started) > globalTimeEnd) { + return ma_node_state_stopped; /* Start time is after the end of the range. */ } /* Getting here means the node is marked as started and is within its start/stop times. */ @@ -75012,14 +75072,14 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde return MA_INVALID_ARGS; /* Invalid output bus index. */ } + globalTimeBeg = globalTime; + globalTimeEnd = globalTime + frameCount; + /* Don't do anything if we're in a stopped state. */ - if (ma_node_get_state_by_time_range(pNode, globalTime, globalTime + frameCount) != ma_node_state_started) { + if (ma_node_get_state_by_time_range(pNode, globalTimeBeg, globalTimeEnd) != ma_node_state_started) { return MA_SUCCESS; /* We're in a stopped state. This is not an error - we just need to not read anything. */ } - - globalTimeBeg = globalTime; - globalTimeEnd = globalTime + frameCount; startTime = ma_node_get_state_time(pNode, ma_node_state_started); stopTime = ma_node_get_state_time(pNode, ma_node_state_stopped); @@ -75032,11 +75092,16 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde therefore need to offset it by a number of frames to accommodate. The same thing applies for the stop time. */ - timeOffsetBeg = (globalTimeBeg < startTime) ? (ma_uint32)(globalTimeEnd - startTime) : 0; + timeOffsetBeg = (globalTimeBeg < startTime) ? (ma_uint32)(startTime - globalTimeBeg) : 0; timeOffsetEnd = (globalTimeEnd > stopTime) ? (ma_uint32)(globalTimeEnd - stopTime) : 0; /* Trim based on the start offset. We need to silence the start of the buffer. */ if (timeOffsetBeg > 0) { + MA_ASSERT(timeOffsetBeg <= frameCount); + if (timeOffsetBeg > frameCount) { + timeOffsetBeg = frameCount; + } + ma_silence_pcm_frames(pFramesOut, timeOffsetBeg, ma_format_f32, ma_node_get_output_channels(pNode, outputBusIndex)); pFramesOut += timeOffsetBeg * ma_node_get_output_channels(pNode, outputBusIndex); frameCount -= timeOffsetBeg; @@ -75044,6 +75109,11 @@ static ma_result ma_node_read_pcm_frames(ma_node* pNode, ma_uint32 outputBusInde /* Trim based on the end offset. We don't need to silence the tail section because we'll just have a reduced value written to pFramesRead. */ if (timeOffsetEnd > 0) { + MA_ASSERT(timeOffsetEnd <= frameCount); + if (timeOffsetEnd > frameCount) { + timeOffsetEnd = frameCount; + } + frameCount -= timeOffsetEnd; } @@ -76458,12 +76528,20 @@ static void ma_sound_set_at_end(ma_sound* pSound, ma_bool32 atEnd) MA_ASSERT(pSound != NULL); ma_atomic_exchange_32(&pSound->atEnd, atEnd); + /* + When this function is called the state of the sound will not yet be in a stopped state. This makes it confusing + because an end callback will intuitively expect ma_sound_is_playing() to return false from inside the callback. + I'm therefore no longer firing the callback here and will instead fire it manually in the *next* processing step + when the state should be set to stopped as expected. + */ + #if 0 /* Fire any callbacks or events. */ if (atEnd) { if (pSound->endCallback != NULL) { pSound->endCallback(pSound->pEndCallbackUserData, pSound); } } + #endif } static ma_bool32 ma_sound_get_at_end(const ma_sound* pSound) @@ -76483,6 +76561,7 @@ MA_API ma_engine_node_config ma_engine_node_config_init(ma_engine* pEngine, ma_e config.isPitchDisabled = (flags & MA_SOUND_FLAG_NO_PITCH) != 0; config.isSpatializationDisabled = (flags & MA_SOUND_FLAG_NO_SPATIALIZATION) != 0; config.monoExpansionMode = pEngine->monoExpansionMode; + config.resampling = pEngine->pitchResamplingConfig; return config; } @@ -76509,7 +76588,7 @@ static void ma_engine_node_update_pitch_if_required(ma_engine_node* pEngineNode) if (isUpdateRequired) { float basePitch = (float)pEngineNode->sampleRate / ma_engine_get_sample_rate(pEngineNode->pEngine); - ma_linear_resampler_set_rate_ratio(&pEngineNode->resampler, basePitch * pEngineNode->oldPitch * pEngineNode->oldDopplerPitch); + ma_resampler_set_rate_ratio(&pEngineNode->resampler, basePitch * pEngineNode->oldPitch * pEngineNode->oldDopplerPitch); } } @@ -76528,22 +76607,6 @@ static ma_bool32 ma_engine_node_is_spatialization_enabled(const ma_engine_node* return !ma_atomic_load_explicit_32(&pEngineNode->isSpatializationDisabled, ma_atomic_memory_order_acquire); } -static ma_uint64 ma_engine_node_get_required_input_frame_count(const ma_engine_node* pEngineNode, ma_uint64 outputFrameCount) -{ - ma_uint64 inputFrameCount = 0; - - if (ma_engine_node_is_pitching_enabled(pEngineNode)) { - ma_result result = ma_linear_resampler_get_required_input_frame_count(&pEngineNode->resampler, outputFrameCount, &inputFrameCount); - if (result != MA_SUCCESS) { - inputFrameCount = 0; - } - } else { - inputFrameCount = outputFrameCount; /* No resampling, so 1:1. */ - } - - return inputFrameCount; -} - static ma_result ma_engine_node_set_volume(ma_engine_node* pEngineNode, float volume) { if (pEngineNode == NULL) { @@ -76685,7 +76748,7 @@ static void ma_engine_node_process_pcm_frames__general(ma_engine_node* pEngineNo ma_uint64 resampleFrameCountIn = framesAvailableIn; ma_uint64 resampleFrameCountOut = framesAvailableOut; - ma_linear_resampler_process_pcm_frames(&pEngineNode->resampler, pRunningFramesIn, &resampleFrameCountIn, pWorkingBuffer, &resampleFrameCountOut); + ma_resampler_process_pcm_frames(&pEngineNode->resampler, pRunningFramesIn, &resampleFrameCountIn, pWorkingBuffer, &resampleFrameCountOut); isWorkingBufferValid = MA_TRUE; framesJustProcessedIn = (ma_uint32)resampleFrameCountIn; @@ -76809,6 +76872,11 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float /* If we're marked at the end we need to stop the sound and do nothing. */ if (ma_sound_at_end(pSound)) { ma_sound_stop(pSound); + + if (pSound->endCallback != NULL) { + pSound->endCallback(pSound->pEndCallbackUserData, pSound); + } + *pFrameCountOut = 0; return; } @@ -76846,55 +76914,74 @@ static void ma_engine_node_process_pcm_frames__sound(ma_node* pNode, const float /* Keep reading until we've read as much as was requested or we reach the end of the data source. */ while (totalFramesRead < frameCount) { ma_uint32 framesRemaining = frameCount - totalFramesRead; - ma_uint32 framesToRead; ma_uint64 framesJustRead; ma_uint32 frameCountIn; ma_uint32 frameCountOut; const float* pRunningFramesIn; float* pRunningFramesOut; - /* - The first thing we need to do is read into the temporary buffer. We can calculate exactly - how many input frames we'll need after resampling. - */ - framesToRead = (ma_uint32)ma_engine_node_get_required_input_frame_count(&pSound->engineNode, framesRemaining); - if (framesToRead > tempCapInFrames) { - framesToRead = tempCapInFrames; - } + /* If there's any input frames sitting in the cache get those processed first. */ + if (pSound->processingCacheFramesRemaining > 0) { + pRunningFramesIn = pSound->pProcessingCache; + frameCountIn = pSound->processingCacheFramesRemaining; - result = ma_data_source_read_pcm_frames(pSound->pDataSource, temp, framesToRead, &framesJustRead); + pRunningFramesOut = ma_offset_pcm_frames_ptr_f32(ppFramesOut[0], totalFramesRead, ma_node_get_output_channels(pNode, 0)); + frameCountOut = framesRemaining; - /* If we reached the end of the sound we'll want to mark it as at the end and stop it. This should never be returned for looping sounds. */ - if (result == MA_AT_END) { - ma_sound_set_at_end(pSound, MA_TRUE); /* This will be set to false in ma_sound_start(). */ - } - - pRunningFramesOut = ma_offset_pcm_frames_ptr_f32(ppFramesOut[0], totalFramesRead, ma_node_get_output_channels(pNode, 0)); - - frameCountIn = (ma_uint32)framesJustRead; - frameCountOut = framesRemaining; - - /* Convert if necessary. */ - if (dataSourceFormat == ma_format_f32) { - /* Fast path. No data conversion necessary. */ - pRunningFramesIn = (float*)temp; ma_engine_node_process_pcm_frames__general(&pSound->engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut); + + MA_ASSERT(frameCountIn <= pSound->processingCacheFramesRemaining); + pSound->processingCacheFramesRemaining -= frameCountIn; + + /* Move any remaining data in the cache down. */ + if (pSound->processingCacheFramesRemaining > 0) { + MA_MOVE_MEMORY(pSound->pProcessingCache, ma_offset_pcm_frames_ptr_f32(pSound->pProcessingCache, frameCountIn, dataSourceChannels), pSound->processingCacheFramesRemaining * ma_get_bytes_per_frame(ma_format_f32, dataSourceChannels)); + } + + totalFramesRead += (ma_uint32)frameCountOut; /* Safe cast. */ + + if (result != MA_SUCCESS || ma_sound_at_end(pSound)) { + break; /* Might have reached the end. */ + } } else { - /* Slow path. Need to do sample format conversion to f32. If we give the f32 buffer the same count as the first temp buffer, we're guaranteed it'll be large enough. */ - float tempf32[MA_DATA_CONVERTER_STACK_BUFFER_SIZE]; /* Do not do `MA_DATA_CONVERTER_STACK_BUFFER_SIZE/sizeof(float)` here like we've done in other places. */ - ma_convert_pcm_frames_format(tempf32, ma_format_f32, temp, dataSourceFormat, framesJustRead, dataSourceChannels, ma_dither_mode_none); + /* Getting here means there's nothing in the cache. Read more data from the data source. */ + if (dataSourceFormat == ma_format_f32) { + /* Fast path. No conversion to f32 necessary. */ + result = ma_data_source_read_pcm_frames(pSound->pDataSource, pSound->pProcessingCache, pSound->processingCacheCap, &framesJustRead); + } else { + /* Slow path. Need to convert to f32. */ + ma_uint64 totalFramesConverted = 0; - /* Now that we have our samples in f32 format we can process like normal. */ - pRunningFramesIn = tempf32; - ma_engine_node_process_pcm_frames__general(&pSound->engineNode, &pRunningFramesIn, &frameCountIn, &pRunningFramesOut, &frameCountOut); - } + while (totalFramesConverted < pSound->processingCacheCap) { + ma_uint64 framesConverted; + ma_uint32 framesToConvertThisIteration = pSound->processingCacheCap - (ma_uint32)totalFramesConverted; + if (framesToConvertThisIteration > tempCapInFrames) { + framesToConvertThisIteration = tempCapInFrames; + } - /* We should have processed all of our input frames since we calculated the required number of input frames at the top. */ - MA_ASSERT(frameCountIn == framesJustRead); - totalFramesRead += (ma_uint32)frameCountOut; /* Safe cast. */ + result = ma_data_source_read_pcm_frames(pSound->pDataSource, temp, framesToConvertThisIteration, &framesConverted); + if (result != MA_SUCCESS) { + break; + } - if (result != MA_SUCCESS || ma_sound_at_end(pSound)) { - break; /* Might have reached the end. */ + ma_convert_pcm_frames_format(ma_offset_pcm_frames_ptr_f32(pSound->pProcessingCache, totalFramesConverted, dataSourceChannels), ma_format_f32, temp, dataSourceFormat, framesConverted, dataSourceChannels, ma_dither_mode_none); + totalFramesConverted += framesConverted; + } + + framesJustRead = totalFramesConverted; + } + + MA_ASSERT(framesJustRead <= pSound->processingCacheCap); + pSound->processingCacheFramesRemaining = (ma_uint32)framesJustRead; + + /* If we reached the end of the sound we'll want to mark it as at the end and stop it. This should never be returned for looping sounds. */ + if (result == MA_AT_END) { + ma_sound_set_at_end(pSound, MA_TRUE); /* This will be set to false in ma_sound_start(). */ + } + + if (result != MA_SUCCESS || ma_sound_at_end(pSound)) { + break; + } } } } @@ -76917,25 +77004,6 @@ static void ma_engine_node_process_pcm_frames__group(ma_node* pNode, const float ma_engine_node_process_pcm_frames__general((ma_engine_node*)pNode, ppFramesIn, pFrameCountIn, ppFramesOut, pFrameCountOut); } -static ma_result ma_engine_node_get_required_input_frame_count__group(ma_node* pNode, ma_uint32 outputFrameCount, ma_uint32* pInputFrameCount) -{ - ma_uint64 inputFrameCount; - - MA_ASSERT(pInputFrameCount != NULL); - - /* Our pitch will affect this calculation. We need to update it. */ - ma_engine_node_update_pitch_if_required((ma_engine_node*)pNode); - - inputFrameCount = ma_engine_node_get_required_input_frame_count((ma_engine_node*)pNode, outputFrameCount); - if (inputFrameCount > 0xFFFFFFFF) { - inputFrameCount = 0xFFFFFFFF; /* Will never happen because miniaudio will only ever process in relatively small chunks. */ - } - - *pInputFrameCount = (ma_uint32)inputFrameCount; - - return MA_SUCCESS; -} - static ma_node_vtable g_ma_engine_node_vtable__sound = { @@ -76949,7 +77017,7 @@ static ma_node_vtable g_ma_engine_node_vtable__sound = static ma_node_vtable g_ma_engine_node_vtable__group = { ma_engine_node_process_pcm_frames__group, - ma_engine_node_get_required_input_frame_count__group, + NULL, /* onGetRequiredInputFrameCount */ 1, /* Groups have one input bus. */ 1, /* Groups have one output bus. */ MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES /* The engine node does resampling so should let miniaudio know about it. */ @@ -76995,9 +77063,10 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo ma_result result; size_t tempHeapSize; ma_node_config baseNodeConfig; - ma_linear_resampler_config resamplerConfig; + ma_resampler_config resamplerConfig; ma_spatializer_config spatializerConfig; ma_gainer_config gainerConfig; + ma_uint32 sampleRate; ma_uint32 channelsIn; ma_uint32 channelsOut; ma_channel defaultStereoChannelMap[2] = {MA_CHANNEL_SIDE_LEFT, MA_CHANNEL_SIDE_RIGHT}; /* <-- Consistent with the default channel map of a stereo listener. Means channel conversion can run on a fast path. */ @@ -77016,6 +77085,7 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo pHeapLayout->sizeInBytes = 0; + sampleRate = (pConfig->sampleRate > 0) ? pConfig->sampleRate : ma_engine_get_sample_rate(pConfig->pEngine); channelsIn = (pConfig->channelsIn != 0) ? pConfig->channelsIn : ma_engine_get_channels(pConfig->pEngine); channelsOut = (pConfig->channelsOut != 0) ? pConfig->channelsOut : ma_engine_get_channels(pConfig->pEngine); @@ -77035,10 +77105,13 @@ static ma_result ma_engine_node_get_heap_layout(const ma_engine_node_config* pCo /* Resmapler. */ - resamplerConfig = ma_linear_resampler_config_init(ma_format_f32, channelsIn, 1, 1); /* Input and output sample rates don't affect the calculation of the heap size. */ - resamplerConfig.lpfOrder = 0; + resamplerConfig = pConfig->resampling; + resamplerConfig.format = ma_format_f32; + resamplerConfig.channels = channelsIn; + resamplerConfig.sampleRateIn = sampleRate; + resamplerConfig.sampleRateOut = ma_engine_get_sample_rate(pConfig->pEngine); - result = ma_linear_resampler_get_heap_size(&resamplerConfig, &tempHeapSize); + result = ma_resampler_get_heap_size(&resamplerConfig, &tempHeapSize); if (result != MA_SUCCESS) { return result; /* Failed to retrieve the size of the heap for the resampler. */ } @@ -77106,7 +77179,7 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p ma_result result; ma_engine_node_heap_layout heapLayout; ma_node_config baseNodeConfig; - ma_linear_resampler_config resamplerConfig; + ma_resampler_config resamplerConfig; ma_fader_config faderConfig; ma_spatializer_config spatializerConfig; ma_panner_config pannerConfig; @@ -77181,10 +77254,13 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p */ /* We'll always do resampling first. */ - resamplerConfig = ma_linear_resampler_config_init(ma_format_f32, baseNodeConfig.pInputChannels[0], pEngineNode->sampleRate, ma_engine_get_sample_rate(pEngineNode->pEngine)); - resamplerConfig.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ + resamplerConfig = pConfig->resampling; + resamplerConfig.format = ma_format_f32; + resamplerConfig.channels = baseNodeConfig.pInputChannels[0]; + resamplerConfig.sampleRateIn = pEngineNode->sampleRate; + resamplerConfig.sampleRateOut = ma_engine_get_sample_rate(pEngineNode->pEngine); - result = ma_linear_resampler_init_preallocated(&resamplerConfig, ma_offset_ptr(pHeap, heapLayout.resamplerOffset), &pEngineNode->resampler); + result = ma_resampler_init_preallocated(&resamplerConfig, ma_offset_ptr(pHeap, heapLayout.resamplerOffset), &pEngineNode->resampler); if (result != MA_SUCCESS) { goto error1; } @@ -77243,7 +77319,7 @@ MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* p /* No need for allocation callbacks here because we use a preallocated heap. */ error3: ma_spatializer_uninit(&pEngineNode->spatializer, NULL); -error2: ma_linear_resampler_uninit(&pEngineNode->resampler, NULL); +error2: ma_resampler_uninit(&pEngineNode->resampler, NULL); error1: ma_node_uninit(&pEngineNode->baseNode, NULL); error0: return result; } @@ -77292,7 +77368,7 @@ MA_API void ma_engine_node_uninit(ma_engine_node* pEngineNode, const ma_allocati } ma_spatializer_uninit(&pEngineNode->spatializer, pAllocationCallbacks); - ma_linear_resampler_uninit(&pEngineNode->resampler, pAllocationCallbacks); + ma_resampler_uninit(&pEngineNode->resampler, pAllocationCallbacks); /* Free the heap last. */ if (pEngineNode->_ownsHeap) { @@ -77314,8 +77390,12 @@ MA_API ma_sound_config ma_sound_config_init_2(ma_engine* pEngine) if (pEngine != NULL) { config.monoExpansionMode = pEngine->monoExpansionMode; + config.pitchResampling = pEngine->pitchResamplingConfig; } else { config.monoExpansionMode = ma_mono_expansion_mode_default; + + config.pitchResampling = ma_resampler_config_init(ma_format_f32, 0, 0, 0, ma_resample_algorithm_linear); + config.pitchResampling.linear.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ } config.rangeEndInPCMFrames = ~((ma_uint64)0); @@ -77337,8 +77417,12 @@ MA_API ma_sound_group_config ma_sound_group_config_init_2(ma_engine* pEngine) if (pEngine != NULL) { config.monoExpansionMode = pEngine->monoExpansionMode; + config.pitchResampling = pEngine->pitchResamplingConfig; } else { config.monoExpansionMode = ma_mono_expansion_mode_default; + + config.pitchResampling = ma_resampler_config_init(ma_format_f32, 0, 0, 0, ma_resample_algorithm_linear); + config.pitchResampling.linear.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ } return config; @@ -77350,8 +77434,12 @@ MA_API ma_engine_config ma_engine_config_init(void) ma_engine_config config; MA_ZERO_OBJECT(&config); - config.listenerCount = 1; /* Always want at least one listener. */ - config.monoExpansionMode = ma_mono_expansion_mode_default; + config.listenerCount = 1; /* Always want at least one listener. */ + config.monoExpansionMode = ma_mono_expansion_mode_default; + config.resourceManagerResampling = ma_resampler_config_init(ma_format_unknown, 0, 0, 0, ma_resample_algorithm_linear); + + config.pitchResampling = ma_resampler_config_init(ma_format_f32, 0, 0, 0, ma_resample_algorithm_linear); + config.pitchResampling.linear.lpfOrder = 0; /* <-- Need to disable low-pass filtering for pitch shifting for now because there's cases where the biquads are becoming unstable. Need to figure out a better fix for this. */ return config; } @@ -77432,6 +77520,7 @@ MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEng pEngine->defaultVolumeSmoothTimeInPCMFrames = engineConfig.defaultVolumeSmoothTimeInPCMFrames; pEngine->onProcess = engineConfig.onProcess; pEngine->pProcessUserData = engineConfig.pProcessUserData; + pEngine->pitchResamplingConfig = engineConfig.pitchResampling; ma_allocation_callbacks_init_copy(&pEngine->allocationCallbacks, &engineConfig.allocationCallbacks); #if !defined(MA_NO_RESOURCE_MANAGER) @@ -77614,6 +77703,7 @@ MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEng resourceManagerConfig.decodedSampleRate = ma_engine_get_sample_rate(pEngine); ma_allocation_callbacks_init_copy(&resourceManagerConfig.allocationCallbacks, &pEngine->allocationCallbacks); resourceManagerConfig.pVFS = engineConfig.pResourceManagerVFS; + resourceManagerConfig.resampling = engineConfig.resourceManagerResampling; /* The Emscripten build cannot use threads unless it's targeting pthreads. */ #if defined(MA_EMSCRIPTEN) && !defined(__EMSCRIPTEN_PTHREADS__) @@ -78339,6 +78429,25 @@ static ma_result ma_sound_init_from_data_source_internal(ma_engine* pEngine, con } + /* + When pulling data from a data source we need a processing cache to hold onto unprocessed input data from the data source + after doing resampling. + */ + if (pSound->pDataSource != NULL) { + pSound->processingCacheFramesRemaining = 0; + pSound->processingCacheCap = ma_node_graph_get_processing_size_in_frames(&pEngine->nodeGraph); + if (pSound->processingCacheCap == 0) { + pSound->processingCacheCap = 512; + } + + pSound->pProcessingCache = (float*)ma_calloc(pSound->processingCacheCap * ma_get_bytes_per_frame(ma_format_f32, engineNodeConfig.channelsIn), &pEngine->allocationCallbacks); + if (pSound->pProcessingCache == NULL) { + ma_engine_node_uninit(&pSound->engineNode, &pEngine->allocationCallbacks); + return MA_OUT_OF_MEMORY; + } + } + + /* Apply initial range and looping state to the data source if applicable. */ if (pConfig->rangeBegInPCMFrames != 0 || pConfig->rangeEndInPCMFrames != ~((ma_uint64)0)) { ma_data_source_set_range_in_pcm_frames(ma_sound_get_data_source(pSound), pConfig->rangeBegInPCMFrames, pConfig->rangeEndInPCMFrames); @@ -78576,6 +78685,11 @@ MA_API void ma_sound_uninit(ma_sound* pSound) */ ma_engine_node_uninit(&pSound->engineNode, &pSound->engineNode.pEngine->allocationCallbacks); + if (pSound->pProcessingCache != NULL) { + ma_free(pSound->pProcessingCache, &pSound->engineNode.pEngine->allocationCallbacks); + pSound->pProcessingCache = NULL; + } + /* Once the sound is detached from the group we can guarantee that it won't be referenced by the mixer thread which means it's safe for us to destroy the data source. */ #ifndef MA_NO_RESOURCE_MANAGER if (pSound->ownsDataSource) { @@ -78671,6 +78785,27 @@ MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_ui return ma_sound_stop_with_fade_in_pcm_frames(pSound, (fadeLengthInMilliseconds * sampleRate) / 1000); } +MA_API void ma_sound_reset_start_time(ma_sound* pSound) +{ + ma_sound_set_start_time_in_pcm_frames(pSound, 0); +} + +MA_API void ma_sound_reset_stop_time(ma_sound* pSound) +{ + ma_sound_set_stop_time_in_pcm_frames(pSound, ~(ma_uint64)0); +} + +MA_API void ma_sound_reset_fade(ma_sound* pSound) +{ + ma_sound_set_fade_in_pcm_frames(pSound, 0, 1, 0); +} + +MA_API void ma_sound_reset_stop_time_and_fade(ma_sound* pSound) +{ + ma_sound_reset_stop_time(pSound); + ma_sound_reset_fade(pSound); +} + MA_API void ma_sound_set_volume(ma_sound* pSound, float volume) { if (pSound == NULL) { @@ -79322,7 +79457,7 @@ MA_API ma_result ma_sound_get_data_format(const ma_sound* pSound, ma_format* pFo } if (pSampleRate != NULL) { - *pSampleRate = pSound->engineNode.resampler.config.sampleRateIn; + *pSampleRate = pSound->engineNode.resampler.sampleRateIn; } if (pChannelMap != NULL) { @@ -82386,7 +82521,6 @@ MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory(void* pUserData, int offset, ma_d ma_dr_wav* pWav = (ma_dr_wav*)pUserData; ma_int64 newCursor; MA_DR_WAV_ASSERT(pWav != NULL); - newCursor = pWav->memoryStream.currentReadPos; if (origin == MA_DR_WAV_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_WAV_SEEK_CUR) { @@ -82440,7 +82574,6 @@ MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory_write(void* pUserData, int offset ma_dr_wav* pWav = (ma_dr_wav*)pUserData; ma_int64 newCursor; MA_DR_WAV_ASSERT(pWav != NULL); - newCursor = pWav->memoryStreamWrite.currentWritePos; if (origin == MA_DR_WAV_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_WAV_SEEK_CUR) { @@ -82449,7 +82582,7 @@ MA_PRIVATE ma_bool32 ma_dr_wav__on_seek_memory_write(void* pUserData, int offset newCursor = (ma_int64)pWav->memoryStreamWrite.dataSize; } else { MA_DR_WAV_ASSERT(!"Invalid seek origin"); - return MA_INVALID_ARGS; + return MA_FALSE; } newCursor += offset; if (newCursor < 0) { @@ -82950,7 +83083,7 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][0]; pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.cachedFrameCount = 2; - if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table)) { + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table)) { return totalFramesRead; } } else { @@ -82972,7 +83105,8 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ pWav->msadpcm.cachedFrames[2] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.cachedFrames[3] = pWav->msadpcm.prevFrames[1][1]; pWav->msadpcm.cachedFrameCount = 2; - if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff2Table)) { + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table) || + pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff2Table)) { return totalFramesRead; } } @@ -83009,6 +83143,9 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ if (pWav->channels == 1) { ma_int32 newSample0; ma_int32 newSample1; + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table)) { + return totalFramesRead; + } newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8; newSample0 += nibble0 * pWav->msadpcm.delta[0]; newSample0 = ma_dr_wav_clamp(newSample0, -32768, 32767); @@ -83033,6 +83170,9 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ } else { ma_int32 newSample0; ma_int32 newSample1; + if (pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[0] >= ma_dr_wav_countof(coeff2Table)) { + return totalFramesRead; + } newSample0 = ((pWav->msadpcm.prevFrames[0][1] * coeff1Table[pWav->msadpcm.predictor[0]]) + (pWav->msadpcm.prevFrames[0][0] * coeff2Table[pWav->msadpcm.predictor[0]])) >> 8; newSample0 += nibble0 * pWav->msadpcm.delta[0]; newSample0 = ma_dr_wav_clamp(newSample0, -32768, 32767); @@ -83042,6 +83182,9 @@ MA_PRIVATE ma_uint64 ma_dr_wav_read_pcm_frames_s16__msadpcm(ma_dr_wav* pWav, ma_ } pWav->msadpcm.prevFrames[0][0] = pWav->msadpcm.prevFrames[0][1]; pWav->msadpcm.prevFrames[0][1] = newSample0; + if (pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff1Table) || pWav->msadpcm.predictor[1] >= ma_dr_wav_countof(coeff2Table)) { + return totalFramesRead; + } newSample1 = ((pWav->msadpcm.prevFrames[1][1] * coeff1Table[pWav->msadpcm.predictor[1]]) + (pWav->msadpcm.prevFrames[1][0] * coeff2Table[pWav->msadpcm.predictor[1]])) >> 8; newSample1 += nibble1 * pWav->msadpcm.delta[1]; newSample1 = ma_dr_wav_clamp(newSample1, -32768, 32767); @@ -84286,6 +84429,10 @@ MA_PRIVATE ma_int16* ma_dr_wav__read_pcm_frames_and_close_s16(ma_dr_wav* pWav, u ma_int16* pSampleData; ma_uint64 framesRead; MA_DR_WAV_ASSERT(pWav != NULL); + if (pWav->channels == 0 || pWav->totalPCMFrameCount > MA_SIZE_MAX / pWav->channels / sizeof(ma_int16)) { + ma_dr_wav_uninit(pWav); + return NULL; + } sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(ma_int16); if (sampleDataSize > MA_SIZE_MAX) { ma_dr_wav_uninit(pWav); @@ -84320,6 +84467,10 @@ MA_PRIVATE float* ma_dr_wav__read_pcm_frames_and_close_f32(ma_dr_wav* pWav, unsi float* pSampleData; ma_uint64 framesRead; MA_DR_WAV_ASSERT(pWav != NULL); + if (pWav->channels == 0 || pWav->totalPCMFrameCount > MA_SIZE_MAX / pWav->channels / sizeof(float)) { + ma_dr_wav_uninit(pWav); + return NULL; + } sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(float); if (sampleDataSize > MA_SIZE_MAX) { ma_dr_wav_uninit(pWav); @@ -84354,6 +84505,10 @@ MA_PRIVATE ma_int32* ma_dr_wav__read_pcm_frames_and_close_s32(ma_dr_wav* pWav, u ma_int32* pSampleData; ma_uint64 framesRead; MA_DR_WAV_ASSERT(pWav != NULL); + if (pWav->channels == 0 || pWav->totalPCMFrameCount > MA_SIZE_MAX / pWav->channels / sizeof(ma_int32)) { + ma_dr_wav_uninit(pWav); + return NULL; + } sampleDataSize = pWav->totalPCMFrameCount * pWav->channels * sizeof(ma_int32); if (sampleDataSize > MA_SIZE_MAX) { ma_dr_wav_uninit(pWav); @@ -85736,7 +85891,7 @@ static MA_INLINE ma_uint32 ma_dr_flac__clz_lzcnt(ma_dr_flac_cache_t x) { ma_uint64 r; __asm__ __volatile__ ( - "lzcnt{ %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" + "rep; bsr{q %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" ); return (ma_uint32)r; } @@ -85744,11 +85899,11 @@ static MA_INLINE ma_uint32 ma_dr_flac__clz_lzcnt(ma_dr_flac_cache_t x) { ma_uint32 r; __asm__ __volatile__ ( - "lzcnt{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" + "rep; bsr{l %1, %0| %0, %1}" : "=r"(r) : "r"(x) : "cc" ); return r; } - #elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !defined(MA_64BIT) + #elif defined(MA_ARM) && (defined(__ARM_ARCH) && __ARM_ARCH >= 5) && !defined(__ARM_ARCH_6M__) && !(defined(__thumb__) && !defined(__thumb2__)) && !defined(MA_64BIT) { unsigned int r; __asm__ __volatile__ ( @@ -88502,8 +88657,9 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea } runningFilePos += 4; metadata.type = blockType; - metadata.pRawData = NULL; metadata.rawDataSize = 0; + metadata.rawDataOffset = runningFilePos; + metadata.pRawData = NULL; switch (blockType) { case MA_DR_FLAC_METADATA_BLOCK_TYPE_APPLICATION: @@ -88703,46 +88859,117 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea return MA_FALSE; } if (onMeta) { - void* pRawData; - const char* pRunningData; - const char* pRunningDataEnd; - pRawData = ma_dr_flac__malloc_from_callbacks(blockSize, pAllocationCallbacks); - if (pRawData == NULL) { + ma_bool32 result = MA_TRUE; + ma_uint32 blockSizeRemaining = blockSize; + char* pMime = NULL; + char* pDescription = NULL; + void* pPictureData = NULL; + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.type, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.type = ma_dr_flac__be2host_32(metadata.data.picture.type); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.mimeLength, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.mimeLength = ma_dr_flac__be2host_32(metadata.data.picture.mimeLength); + pMime = (char*)ma_dr_flac__malloc_from_callbacks(metadata.data.picture.mimeLength + 1, pAllocationCallbacks); + if (pMime == NULL) { + result = MA_FALSE; + goto done_flac; + } + if (blockSizeRemaining < metadata.data.picture.mimeLength || onRead(pUserData, pMime, metadata.data.picture.mimeLength) != metadata.data.picture.mimeLength) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= metadata.data.picture.mimeLength; + pMime[metadata.data.picture.mimeLength] = '\0'; + metadata.data.picture.mime = (const char*)pMime; + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.descriptionLength, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.descriptionLength = ma_dr_flac__be2host_32(metadata.data.picture.descriptionLength); + pDescription = (char*)ma_dr_flac__malloc_from_callbacks(metadata.data.picture.descriptionLength + 1, pAllocationCallbacks); + if (pDescription == NULL) { + result = MA_FALSE; + goto done_flac; + } + if (blockSizeRemaining < metadata.data.picture.descriptionLength || onRead(pUserData, pDescription, metadata.data.picture.descriptionLength) != metadata.data.picture.descriptionLength) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= metadata.data.picture.descriptionLength; + pDescription[metadata.data.picture.descriptionLength] = '\0'; + metadata.data.picture.description = (const char*)pDescription; + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.width, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.width = ma_dr_flac__be2host_32(metadata.data.picture.width); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.height, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.height = ma_dr_flac__be2host_32(metadata.data.picture.height); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.colorDepth, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.colorDepth = ma_dr_flac__be2host_32(metadata.data.picture.colorDepth); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.indexColorCount, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.indexColorCount = ma_dr_flac__be2host_32(metadata.data.picture.indexColorCount); + if (blockSizeRemaining < 4 || onRead(pUserData, &metadata.data.picture.pictureDataSize, 4) != 4) { + result = MA_FALSE; + goto done_flac; + } + blockSizeRemaining -= 4; + metadata.data.picture.pictureDataSize = ma_dr_flac__be2host_32(metadata.data.picture.pictureDataSize); + if (blockSizeRemaining < metadata.data.picture.pictureDataSize) { + result = MA_FALSE; + goto done_flac; + } + metadata.data.picture.pictureDataOffset = runningFilePos + (blockSize - blockSizeRemaining); + #ifndef MA_DR_FLAC_NO_PICTURE_METADATA_MALLOC + pPictureData = ma_dr_flac__malloc_from_callbacks(metadata.data.picture.pictureDataSize, pAllocationCallbacks); + if (pPictureData != NULL) { + if (onRead(pUserData, pPictureData, metadata.data.picture.pictureDataSize) != metadata.data.picture.pictureDataSize) { + result = MA_FALSE; + goto done_flac; + } + } else + #endif + { + if (!onSeek(pUserData, metadata.data.picture.pictureDataSize, MA_DR_FLAC_SEEK_CUR)) { + result = MA_FALSE; + goto done_flac; + } + } + blockSizeRemaining -= metadata.data.picture.pictureDataSize; + (void)blockSizeRemaining; + metadata.data.picture.pPictureData = (const ma_uint8*)pPictureData; + if (metadata.data.picture.pictureDataOffset != 0 || metadata.data.picture.pPictureData != NULL) { + onMeta(pUserDataMD, &metadata); + } else { + } + done_flac: + ma_dr_flac__free_from_callbacks(pMime, pAllocationCallbacks); + ma_dr_flac__free_from_callbacks(pDescription, pAllocationCallbacks); + ma_dr_flac__free_from_callbacks(pPictureData, pAllocationCallbacks); + if (result != MA_TRUE) { return MA_FALSE; } - if (onRead(pUserData, pRawData, blockSize) != blockSize) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - metadata.pRawData = pRawData; - metadata.rawDataSize = blockSize; - pRunningData = (const char*)pRawData; - pRunningDataEnd = (const char*)pRawData + blockSize; - metadata.data.picture.type = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.mimeLength = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - if ((pRunningDataEnd - pRunningData) - 24 < (ma_int64)metadata.data.picture.mimeLength) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - metadata.data.picture.mime = pRunningData; pRunningData += metadata.data.picture.mimeLength; - metadata.data.picture.descriptionLength = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - if ((pRunningDataEnd - pRunningData) - 20 < (ma_int64)metadata.data.picture.descriptionLength) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - metadata.data.picture.description = pRunningData; pRunningData += metadata.data.picture.descriptionLength; - metadata.data.picture.width = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.height = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.colorDepth = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.indexColorCount = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.pictureDataSize = ma_dr_flac__be2host_32_ptr_unaligned(pRunningData); pRunningData += 4; - metadata.data.picture.pPictureData = (const ma_uint8*)pRunningData; - if (pRunningDataEnd - pRunningData < (ma_int64)metadata.data.picture.pictureDataSize) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; - } - onMeta(pUserDataMD, &metadata); - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); } } break; case MA_DR_FLAC_METADATA_BLOCK_TYPE_PADDING: @@ -88768,12 +88995,15 @@ static ma_bool32 ma_dr_flac__read_and_decode_metadata(ma_dr_flac_read_proc onRea { if (onMeta) { void* pRawData = ma_dr_flac__malloc_from_callbacks(blockSize, pAllocationCallbacks); - if (pRawData == NULL) { - return MA_FALSE; - } - if (onRead(pUserData, pRawData, blockSize) != blockSize) { - ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); - return MA_FALSE; + if (pRawData != NULL) { + if (onRead(pUserData, pRawData, blockSize) != blockSize) { + ma_dr_flac__free_from_callbacks(pRawData, pAllocationCallbacks); + return MA_FALSE; + } + } else { + if (!onSeek(pUserData, blockSize, MA_DR_FLAC_SEEK_CUR)) { + return MA_FALSE; + } } metadata.pRawData = pRawData; metadata.rawDataSize = blockSize; @@ -89832,7 +90062,6 @@ static ma_bool32 ma_dr_flac__on_seek_memory(void* pUserData, int offset, ma_dr_f ma_dr_flac__memory_stream* memoryStream = (ma_dr_flac__memory_stream*)pUserData; ma_int64 newCursor; MA_DR_FLAC_ASSERT(memoryStream != NULL); - newCursor = memoryStream->currentReadPos; if (origin == MA_DR_FLAC_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_FLAC_SEEK_CUR) { @@ -92153,56 +92382,41 @@ static type* ma_dr_flac__full_read_and_close_ ## extension (ma_dr_flac* pFlac, u { \ type* pSampleData = NULL; \ ma_uint64 totalPCMFrameCount; \ + type buffer[4096]; \ + ma_uint64 pcmFramesRead; \ + size_t sampleDataBufferSize = sizeof(buffer); \ \ MA_DR_FLAC_ASSERT(pFlac != NULL); \ \ - totalPCMFrameCount = pFlac->totalPCMFrameCount; \ + totalPCMFrameCount = 0; \ \ - if (totalPCMFrameCount == 0) { \ - type buffer[4096]; \ - ma_uint64 pcmFramesRead; \ - size_t sampleDataBufferSize = sizeof(buffer); \ + pSampleData = (type*)ma_dr_flac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \ + if (pSampleData == NULL) { \ + goto on_error; \ + } \ \ - pSampleData = (type*)ma_dr_flac__malloc_from_callbacks(sampleDataBufferSize, &pFlac->allocationCallbacks); \ - if (pSampleData == NULL) { \ - goto on_error; \ - } \ + while ((pcmFramesRead = (ma_uint64)ma_dr_flac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \ + if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \ + type* pNewSampleData; \ + size_t newSampleDataBufferSize; \ \ - while ((pcmFramesRead = (ma_uint64)ma_dr_flac_read_pcm_frames_##extension(pFlac, sizeof(buffer)/sizeof(buffer[0])/pFlac->channels, buffer)) > 0) { \ - if (((totalPCMFrameCount + pcmFramesRead) * pFlac->channels * sizeof(type)) > sampleDataBufferSize) { \ - type* pNewSampleData; \ - size_t newSampleDataBufferSize; \ - \ - newSampleDataBufferSize = sampleDataBufferSize * 2; \ - pNewSampleData = (type*)ma_dr_flac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \ - if (pNewSampleData == NULL) { \ - ma_dr_flac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \ - goto on_error; \ - } \ - \ - sampleDataBufferSize = newSampleDataBufferSize; \ - pSampleData = pNewSampleData; \ + newSampleDataBufferSize = sampleDataBufferSize * 2; \ + pNewSampleData = (type*)ma_dr_flac__realloc_from_callbacks(pSampleData, newSampleDataBufferSize, sampleDataBufferSize, &pFlac->allocationCallbacks); \ + if (pNewSampleData == NULL) { \ + ma_dr_flac__free_from_callbacks(pSampleData, &pFlac->allocationCallbacks); \ + goto on_error; \ } \ \ - MA_DR_FLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \ - totalPCMFrameCount += pcmFramesRead; \ + sampleDataBufferSize = newSampleDataBufferSize; \ + pSampleData = pNewSampleData; \ } \ \ + MA_DR_FLAC_COPY_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), buffer, (size_t)(pcmFramesRead*pFlac->channels*sizeof(type))); \ + totalPCMFrameCount += pcmFramesRead; \ + } \ + \ \ - MA_DR_FLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \ - } else { \ - ma_uint64 dataSize = totalPCMFrameCount*pFlac->channels*sizeof(type); \ - if (dataSize > (ma_uint64)MA_SIZE_MAX) { \ - goto on_error; \ - } \ - \ - pSampleData = (type*)ma_dr_flac__malloc_from_callbacks((size_t)dataSize, &pFlac->allocationCallbacks); \ - if (pSampleData == NULL) { \ - goto on_error; \ - } \ - \ - totalPCMFrameCount = ma_dr_flac_read_pcm_frames_##extension(pFlac, pFlac->totalPCMFrameCount, pSampleData); \ - } \ + MA_DR_FLAC_ZERO_MEMORY(pSampleData + (totalPCMFrameCount*pFlac->channels), (size_t)(sampleDataBufferSize - totalPCMFrameCount*pFlac->channels*sizeof(type))); \ \ if (sampleRateOut) *sampleRateOut = pFlac->sampleRate; \ if (channelsOut) *channelsOut = pFlac->channels; \ @@ -92488,12 +92702,9 @@ MA_API const char* ma_dr_mp3_version_string(void) #define MA_DR_MP3_NO_SIMD #endif #define MA_DR_MP3_OFFSET_PTR(p, offset) ((void*)((ma_uint8*)(p) + (offset))) -#define MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE 2304 #ifndef MA_DR_MP3_MAX_FRAME_SYNC_MATCHES #define MA_DR_MP3_MAX_FRAME_SYNC_MATCHES 10 #endif -#define MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES MA_DR_MP3_MAX_FREE_FORMAT_FRAME_SIZE -#define MA_DR_MP3_MAX_BITRESERVOIR_BYTES 511 #define MA_DR_MP3_SHORT_BLOCK_TYPE 2 #define MA_DR_MP3_STOP_BLOCK_TYPE 3 #define MA_DR_MP3_MODE_MONO 3 @@ -92543,7 +92754,7 @@ MA_API const char* ma_dr_mp3_version_string(void) #define MA_DR_MP3_VMUL_S(x, s) _mm_mul_ps(x, _mm_set1_ps(s)) #define MA_DR_MP3_VREV(x) _mm_shuffle_ps(x, x, _MM_SHUFFLE(0, 1, 2, 3)) typedef __m128 ma_dr_mp3_f4; -#if defined(_MSC_VER) || defined(MA_DR_MP3_ONLY_SIMD) +#if (defined(_MSC_VER) || defined(MA_DR_MP3_ONLY_SIMD)) && !defined(__clang__) #define ma_dr_mp3_cpuid __cpuid #else static __inline__ __attribute__((always_inline)) void ma_dr_mp3_cpuid(int CPUInfo[], const int InfoType) @@ -92659,11 +92870,6 @@ static __inline__ __attribute__((always_inline)) ma_int32 ma_dr_mp3_clip_int16_a #define MA_DR_MP3_FREE(p) free((p)) #endif typedef struct -{ - const ma_uint8 *buf; - int pos, limit; -} ma_dr_mp3_bs; -typedef struct { float scf[3*64]; ma_uint8 total_bands, stereo_bands, bitalloc[64], scfcod[64]; @@ -92672,22 +92878,6 @@ typedef struct { ma_uint8 tab_offset, code_tab_width, band_count; } ma_dr_mp3_L12_subband_alloc; -typedef struct -{ - const ma_uint8 *sfbtab; - ma_uint16 part_23_length, big_values, scalefac_compress; - ma_uint8 global_gain, block_type, mixed_block_flag, n_long_sfb, n_short_sfb; - ma_uint8 table_select[3], region_count[3], subblock_gain[3]; - ma_uint8 preflag, scalefac_scale, count1_table, scfsi; -} ma_dr_mp3_L3_gr_info; -typedef struct -{ - ma_dr_mp3_bs bs; - ma_uint8 maindata[MA_DR_MP3_MAX_BITRESERVOIR_BYTES + MA_DR_MP3_MAX_L3_FRAME_PAYLOAD_BYTES]; - ma_dr_mp3_L3_gr_info gr_info[4]; - float grbuf[2][576], scf[40], syn[18 + 15][2*32]; - ma_uint8 ist_pos[2][39]; -} ma_dr_mp3dec_scratch; static void ma_dr_mp3_bs_init(ma_dr_mp3_bs *bs, const ma_uint8 *data, int bytes) { bs->buf = data; @@ -93070,7 +93260,7 @@ static float ma_dr_mp3_L3_ldexp_q2(float y, int exp_q2) } while ((exp_q2 -= e) > 0); return y; } -#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif @@ -93132,7 +93322,7 @@ static void ma_dr_mp3_L3_decode_scalefactors(const ma_uint8 *hdr, ma_uint8 *ist_ scf[i] = ma_dr_mp3_L3_ldexp_q2(gain, iscf[i] << scf_shift); } } -#if (defined(__GNUC__) && (__GNUC__ >= 14)) && !defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 13)) && !defined(__clang__) #pragma GCC diagnostic pop #endif static const float ma_dr_mp3_g_pow43[129 + 16] = { @@ -94060,7 +94250,6 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int int i = 0, igr, frame_size = 0, success = 1; const ma_uint8 *hdr; ma_dr_mp3_bs bs_frame[1]; - ma_dr_mp3dec_scratch scratch; if (mp3_bytes > 4 && dec->header[0] == 0xff && ma_dr_mp3_hdr_compare(dec->header, mp3)) { frame_size = ma_dr_mp3_hdr_frame_bytes(mp3, dec->free_format_bytes) + ma_dr_mp3_hdr_padding(mp3); @@ -94093,23 +94282,23 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int } if (info->layer == 3) { - int main_data_begin = ma_dr_mp3_L3_read_side_info(bs_frame, scratch.gr_info, hdr); + int main_data_begin = ma_dr_mp3_L3_read_side_info(bs_frame, dec->scratch.gr_info, hdr); if (main_data_begin < 0 || bs_frame->pos > bs_frame->limit) { ma_dr_mp3dec_init(dec); return 0; } - success = ma_dr_mp3_L3_restore_reservoir(dec, bs_frame, &scratch, main_data_begin); + success = ma_dr_mp3_L3_restore_reservoir(dec, bs_frame, &dec->scratch, main_data_begin); if (success && pcm != NULL) { for (igr = 0; igr < (MA_DR_MP3_HDR_TEST_MPEG1(hdr) ? 2 : 1); igr++, pcm = MA_DR_MP3_OFFSET_PTR(pcm, sizeof(ma_dr_mp3d_sample_t)*576*info->channels)) { - MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); - ma_dr_mp3_L3_decode(dec, &scratch, scratch.gr_info + igr*info->channels, info->channels); - ma_dr_mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 18, info->channels, (ma_dr_mp3d_sample_t*)pcm, scratch.syn[0]); + MA_DR_MP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); + ma_dr_mp3_L3_decode(dec, &dec->scratch, dec->scratch.gr_info + igr*info->channels, info->channels); + ma_dr_mp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 18, info->channels, (ma_dr_mp3d_sample_t*)pcm, dec->scratch.syn[0]); } } - ma_dr_mp3_L3_save_reservoir(dec, &scratch); + ma_dr_mp3_L3_save_reservoir(dec, &dec->scratch); } else { #ifdef MA_DR_MP3_ONLY_MP3 @@ -94120,15 +94309,15 @@ MA_API int ma_dr_mp3dec_decode_frame(ma_dr_mp3dec *dec, const ma_uint8 *mp3, int return ma_dr_mp3_hdr_frame_samples(hdr); } ma_dr_mp3_L12_read_scale_info(hdr, bs_frame, sci); - MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); + MA_DR_MP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); for (i = 0, igr = 0; igr < 3; igr++) { - if (12 == (i += ma_dr_mp3_L12_dequantize_granule(scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) + if (12 == (i += ma_dr_mp3_L12_dequantize_granule(dec->scratch.grbuf[0] + i, bs_frame, sci, info->layer | 1))) { i = 0; - ma_dr_mp3_L12_apply_scf_384(sci, sci->scf + igr, scratch.grbuf[0]); - ma_dr_mp3d_synth_granule(dec->qmf_state, scratch.grbuf[0], 12, info->channels, (ma_dr_mp3d_sample_t*)pcm, scratch.syn[0]); - MA_DR_MP3_ZERO_MEMORY(scratch.grbuf[0], 576*2*sizeof(float)); + ma_dr_mp3_L12_apply_scf_384(sci, sci->scf + igr, dec->scratch.grbuf[0]); + ma_dr_mp3d_synth_granule(dec->qmf_state, dec->scratch.grbuf[0], 12, info->channels, (ma_dr_mp3d_sample_t*)pcm, dec->scratch.syn[0]); + MA_DR_MP3_ZERO_MEMORY(dec->scratch.grbuf[0], 576*2*sizeof(float)); pcm = MA_DR_MP3_OFFSET_PTR(pcm, sizeof(ma_dr_mp3d_sample_t)*384*info->channels); } if (bs_frame->pos > bs_frame->limit) @@ -94587,19 +94776,22 @@ static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc on ((ma_uint32)ape[25] << 8) | ((ma_uint32)ape[26] << 16) | ((ma_uint32)ape[27] << 24); - streamEndOffset -= 32 + tagSize; - streamLen -= 32 + tagSize; - if (onMeta != NULL) { - if (onSeek(pUserData, streamEndOffset, MA_DR_MP3_SEEK_END)) { - size_t apeTagSize = (size_t)tagSize + 32; - ma_uint8* pTagData = (ma_uint8*)ma_dr_mp3_malloc(apeTagSize, pAllocationCallbacks); - if (pTagData != NULL) { - if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) { - ma_dr_mp3__on_meta(pMP3, MA_DR_MP3_METADATA_TYPE_APE, pTagData, apeTagSize); + if (32 + tagSize < streamLen) { + streamEndOffset -= 32 + tagSize; + streamLen -= 32 + tagSize; + if (onMeta != NULL) { + if (onSeek(pUserData, streamEndOffset, MA_DR_MP3_SEEK_END)) { + size_t apeTagSize = (size_t)tagSize + 32; + ma_uint8* pTagData = (ma_uint8*)ma_dr_mp3_malloc(apeTagSize, pAllocationCallbacks); + if (pTagData != NULL) { + if (onRead(pUserData, pTagData, apeTagSize) == apeTagSize) { + ma_dr_mp3__on_meta(pMP3, MA_DR_MP3_METADATA_TYPE_APE, pTagData, apeTagSize); + } + ma_dr_mp3_free(pTagData, pAllocationCallbacks); } - ma_dr_mp3_free(pTagData, pAllocationCallbacks); } } + } else { } } } @@ -94687,7 +94879,6 @@ static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc on { ma_dr_mp3_bs bs; ma_dr_mp3_L3_gr_info grInfo[4]; - const ma_uint8* pTagData = pFirstFrameData; ma_dr_mp3_bs_init(&bs, pFirstFrameData + MA_DR_MP3_HDR_SIZE, firstFrameInfo.frame_bytes - MA_DR_MP3_HDR_SIZE); if (MA_DR_MP3_HDR_IS_CRC(pFirstFrameData)) { ma_dr_mp3_bs_get_bits(&bs, 16); @@ -94695,6 +94886,7 @@ static ma_bool32 ma_dr_mp3_init_internal(ma_dr_mp3* pMP3, ma_dr_mp3_read_proc on if (ma_dr_mp3_L3_read_side_info(&bs, grInfo, pFirstFrameData) >= 0) { ma_bool32 isXing = MA_FALSE; ma_bool32 isInfo = MA_FALSE; + const ma_uint8* pTagData; const ma_uint8* pTagDataBeg; pTagDataBeg = pFirstFrameData + MA_DR_MP3_HDR_SIZE + (bs.pos/8); pTagData = pTagDataBeg; @@ -94794,7 +94986,6 @@ static ma_bool32 ma_dr_mp3__on_seek_memory(void* pUserData, int byteOffset, ma_d ma_dr_mp3* pMP3 = (ma_dr_mp3*)pUserData; ma_int64 newCursor; MA_DR_MP3_ASSERT(pMP3 != NULL); - newCursor = pMP3->memory.currentReadPos; if (origin == MA_DR_MP3_SEEK_SET) { newCursor = 0; } else if (origin == MA_DR_MP3_SEEK_CUR) { @@ -95445,6 +95636,8 @@ static float* ma_dr_mp3__full_read_and_close_f32(ma_dr_mp3* pMP3, ma_dr_mp3_conf pNewFrames = (float*)ma_dr_mp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); if (pNewFrames == NULL) { ma_dr_mp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + pFrames = NULL; + totalFramesRead = 0; break; } pFrames = pNewFrames; @@ -95496,6 +95689,8 @@ static ma_int16* ma_dr_mp3__full_read_and_close_s16(ma_dr_mp3* pMP3, ma_dr_mp3_c pNewFrames = (ma_int16*)ma_dr_mp3__realloc_from_callbacks(pFrames, (size_t)newFramesBufferSize, (size_t)oldFramesBufferSize, &pMP3->allocationCallbacks); if (pNewFrames == NULL) { ma_dr_mp3__free_from_callbacks(pFrames, &pMP3->allocationCallbacks); + pFrames = NULL; + totalFramesRead = 0; break; } pFrames = pNewFrames; @@ -95646,4 +95841,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ \ No newline at end of file +*/ diff --git a/src/external/rlsw.h b/src/external/rlsw.h index 80fb02c4f..aad99f937 100644 --- a/src/external/rlsw.h +++ b/src/external/rlsw.h @@ -1177,7 +1177,7 @@ static inline void sw_float_to_unorm8_simd(uint8_t dst[4], const float src[4]) static inline void sw_float_from_unorm8_simd(float dst[4], const uint8_t src[4]) { #if defined(SW_HAS_NEON) - uint8x8_t bytes8 = vld1_u8(src); //< Read 8 bytes, faster, but let's hope we're not at the end of the page (unlikely)... + uint8x8_t bytes8 = vld1_u8(src); // Reading 8 bytes, faster, but let's hope not hitting the end of the page (unlikely)... uint16x8_t bytes16 = vmovl_u8(bytes8); uint32x4_t ints = vmovl_u16(vget_low_u16(bytes16)); float32x4_t floats = vcvtq_f32_u32(ints); @@ -1224,8 +1224,8 @@ static inline uint32_t sw_half_to_float_ui(uint16_t h) // denormal: flush to zero r = (em < (1 << 10))? 0 : r; - // infinity/NaN; note that we preserve NaN payload as a byproduct of unifying inf/nan cases - // 112 is an exponent bias fixup; since we already applied it once, applying it twice converts 31 to 255 + // NOTE: infinity/NaN; NaN payload is preserved as a byproduct of unifying inf/nan cases + // 112 is an exponent bias fixup; since it is already applied once, applying it twice converts 31 to 255 r += (em >= (31 << 10))? (112 << 23) : 0; return s | r; @@ -1252,7 +1252,7 @@ static inline uint16_t sw_half_from_float_ui(uint32_t ui) // Overflow: infinity; 143 encodes exponent 16 h = (em >= (143 << 23))? 0x7c00 : h; - // NaN; note that we convert all types of NaN to qNaN + // NOTE: NaN; all types of NaN aree converted to qNaN h = (em > (255 << 23))? 0x7e00 : h; return (uint16_t)(s | h); @@ -1918,8 +1918,8 @@ static inline void sw_texture_sample_nearest(float *color, const sw_texture_t *t static inline void sw_texture_sample_linear(float *color, const sw_texture_t *tex, float u, float v) { - // TODO: With a bit more cleverness we could clearly reduce the - // number of operations here, but for now it works fine + // TODO: With a bit more cleverness thee number of operations can + // be clearly reduced, but for now it works fine float xf = (u*tex->width) - 0.5f; float yf = (v*tex->height) - 0.5f; @@ -1933,7 +1933,7 @@ static inline void sw_texture_sample_linear(float *color, const sw_texture_t *te int x1 = x0 + 1; int y1 = y0 + 1; - // NOTE: If the textures are POT we could avoid the division for SW_REPEAT + // NOTE: If the textures are POT, avoid the division for SW_REPEAT if (tex->sWrap == SW_CLAMP) { @@ -1974,7 +1974,7 @@ static inline void sw_texture_sample_linear(float *color, const sw_texture_t *te static inline void sw_texture_sample(float *color, const sw_texture_t *tex, float u, float v, float dUdx, float dUdy, float dVdx, float dVdy) { // Previous method: There is no need to compute the square root - // because using the squared value, the comparison remains `L2 > 1.0f*1.0f` + // because using the squared value, the comparison remains (L2 > 1.0f*1.0f) //float du = sqrtf(dUdx*dUdx + dUdy*dUdy); //float dv = sqrtf(dVdx*dVdx + dVdy*dVdy); //float L = (du > dv)? du : dv; @@ -2204,12 +2204,12 @@ static inline bool sw_polygon_clip(sw_vertex_t polygon[SW_MAX_CLIPPED_POLYGON_VE static inline bool sw_triangle_face_culling(void) { // NOTE: Face culling is done before clipping to avoid unnecessary computations - // To handle triangles crossing the w=0 plane correctly, - // we perform the winding order test in homogeneous coordinates directly, - // before the perspective division (division by w) - // This test determines the orientation of the triangle in the (x,y,w) plane, - // which corresponds to the projected 2D winding order sign, - // even with negative w values + // To handle triangles crossing the w=0 plane correctly, + // the winding order test is performeed in homogeneous coordinates directly, + // before the perspective division (division by w) + // This test determines the orientation of the triangle in the (x,y,w) plane, + // which corresponds to the projected 2D winding order sign, + // even with negative w values // Preload homogeneous coordinates into local variables const float *h0 = RLSW.vertexBuffer[0].homogeneous; @@ -2558,13 +2558,13 @@ static inline void sw_triangle_render(void) static inline bool sw_quad_face_culling(void) { // NOTE: Face culling is done before clipping to avoid unnecessary computations - // To handle quads crossing the w=0 plane correctly, - // we perform the winding order test in homogeneous coordinates directly, - // before the perspective division (division by w) - // For a convex quad with vertices P0, P1, P2, P3 in sequential order, - // the winding order of the quad is the same as the winding order - // of the triangle P0 P1 P2. We use the homogeneous triangle - // winding test on this first triangle + // To handle quads crossing the w=0 plane correctly, + // the winding order test is performed in homogeneous coordinates directly, + // before the perspective division (division by w) + // For a convex quad with vertices P0, P1, P2, P3 in sequential order, + // the winding order of the quad is the same as the winding order + // of the triangle P0 P1 P2. The homogeneous triangle is used on + // winding test on this first triangle // Preload homogeneous coordinates into local variables const float *h0 = RLSW.vertexBuffer[0].homogeneous; @@ -2649,7 +2649,7 @@ static inline bool sw_quad_is_axis_aligned(void) { // Reject quads with perspective projection // The fast path assumes affine (non-perspective) quads, - // so we require all vertices to have homogeneous w = 1.0 + // so it's required for all vertices to have homogeneous w = 1.0 for (int i = 0; i < 4; i++) { if (RLSW.vertexBuffer[i].homogeneous[3] != 1.0f) return false; @@ -2721,7 +2721,7 @@ static inline void sw_quad_sort_cw(const sw_vertex_t* *output) // TODO: REVIEW: Could a perfectly aligned quad, where one of the four points has a different depth, // still appear perfectly aligned from a certain point of view? -// Because in that case, we would still need to perform perspective division for textures and colors... +// Because in that case, it's still needed to perform perspective division for textures and colors... #define DEFINE_QUAD_RASTER_AXIS_ALIGNED(FUNC_NAME, ENABLE_TEXTURE, ENABLE_DEPTH_TEST, ENABLE_COLOR_BLEND) \ static inline void FUNC_NAME(void) \ { \ @@ -3090,7 +3090,7 @@ static inline void FUNC_NAME(const sw_vertex_t *v0, const sw_vertex_t *v1) \ \ for (int i = 0; i < numPixels; i++) \ { \ - /* REVIEW: May require reviewing projection details */ \ + /* TODO: REVIEW: May require reviewing projection details */ \ int px = (int)(x - 0.5f); \ int py = (int)(y - 0.5f); \ \ @@ -3721,7 +3721,7 @@ void swBlitFramebuffer(int xDst, int yDst, int wDst, int hDst, int xSrc, int ySr ySrc = sw_clampi(ySrc, 0, hSrc); // Check if the sizes are identical after clamping the source to avoid unexpected issues - // REVIEW: This repeats the operations if true, so we could make a copy function without these checks + // TODO: REVIEW: This repeats the operations if true, so a copy function can be made without these checks if (xDst == xSrc && yDst == ySrc && wDst == wSrc && hDst == hSrc) { swCopyFramebuffer(xSrc, ySrc, wSrc, hSrc, format, type, pixels); diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 6122f9a74..65236be0f 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -886,8 +886,8 @@ void ClosePlatform(void) // NOTE: Reset global state in case the activity is being relaunched if (platform.app->destroyRequested != 0) { - CORE = (CoreData){0}; - platform = (PlatformData){0}; + CORE = (CoreData){ 0 }; + platform = (PlatformData){ 0 }; } } @@ -1189,7 +1189,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) if (FLAG_IS_SET(source, AINPUT_SOURCE_JOYSTICK) || FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) { - // For now we'll assume a single gamepad which we "detect" on its input event + // Assuming a single gamepad, "detected" on its input event CORE.Input.Gamepad.ready[0] = true; CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_X] = AMotionEvent_getAxisValue( @@ -1256,7 +1256,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) FLAG_IS_SET(source, AINPUT_SOURCE_GAMEPAD)) && !FLAG_IS_SET(source, AINPUT_SOURCE_KEYBOARD)) { - // For now we'll assume a single gamepad which we "detect" on its input event + // Assuming a single gamepad, "detected" on its input event CORE.Input.Gamepad.ready[0] = true; GamepadButton button = AndroidTranslateGamepadButton(keycode); diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index f39e256aa..e3078dacf 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -100,7 +100,7 @@ #include // Required for: usleep() //#define GLFW_EXPOSE_NATIVE_COCOA // WARNING: Fails due to type redefinition - void *glfwGetCocoaWindow(GLFWwindow* handle); + void *glfwGetCocoaWindow(GLFWwindow *handle); #include "GLFW/glfw3native.h" // Required for: glfwGetCocoaWindow() #endif @@ -224,8 +224,8 @@ void ToggleFullscreen(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); - CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x); - CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y); + CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); + CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height*scaleDpi.y); } #endif @@ -303,8 +303,8 @@ void ToggleBorderlessWindowed(void) if (FLAG_IS_SET(CORE.Window.flags, FLAG_WINDOW_HIGHDPI)) { Vector2 scaleDpi = GetWindowScaleDPI(); - CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width * scaleDpi.x); - CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height * scaleDpi.y); + CORE.Window.screen.width = (unsigned int)(CORE.Window.screen.width*scaleDpi.x); + CORE.Window.screen.height = (unsigned int)(CORE.Window.screen.height*scaleDpi.y); } #endif @@ -602,7 +602,7 @@ void SetWindowIcon(Image image) icon[0].height = image.height; icon[0].pixels = (unsigned char *)image.data; - // NOTE 1: We only support one image icon + // NOTE 1: Only one image icon supported // NOTE 2: The specified image data is copied before this function returns glfwSetWindowIcon(platform.handle, 1, icon); } @@ -833,7 +833,7 @@ int GetCurrentMonitor(void) } else { - // In case the window is between two monitors, we use below logic + // In case the window is between two monitors, below logic is used // to try to detect the "current monitor" for that window, note that // this is probably an overengineered solution for a very side case // trying to match SDL behaviour @@ -1186,7 +1186,7 @@ void SetMouseCursor(int cursor) if (cursor == MOUSE_CURSOR_DEFAULT) glfwSetCursor(platform.handle, NULL); else { - // NOTE: We are relating internal GLFW enum values to our MouseCursor enum values + // NOTE: Mapping internal GLFW enum values to MouseCursor enum values glfwSetCursor(platform.handle, glfwCreateStandardCursor(0x00036000 + cursor)); } } @@ -1211,7 +1211,7 @@ void PollInputEvents(void) CORE.Input.Keyboard.charPressedQueueCount = 0; // Reset last gamepad button/axis registered state - CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN + CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN; //CORE.Input.Gamepad.axisCount = 0; // Keyboard/Mouse input polling (automatically managed by GLFW3 through callback) @@ -1247,7 +1247,7 @@ void PollInputEvents(void) CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; // Check if gamepads are ready - // NOTE: We do it here in case of disconnection + // NOTE: Doing it here in case of disconnection for (int i = 0; i < MAX_GAMEPADS; i++) { if (glfwJoystickPresent(i)) CORE.Input.Gamepad.ready[i] = true; @@ -1263,7 +1263,7 @@ void PollInputEvents(void) for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; // Get current gamepad state - // NOTE: There is no callback available, so we get it manually + // NOTE: There is no callback available, getting it manually GLFWgamepadstate state = { 0 }; int result = glfwGetGamepadState(i, &state); // This remaps all gamepads so they have their buttons mapped like an xbox controller if (result == GLFW_FALSE) // No joystick is connected, no gamepad mapping or an error occurred @@ -1359,8 +1359,8 @@ void PollInputEvents(void) //---------------------------------------------------------------------------------- // Module Internal Functions Definition //---------------------------------------------------------------------------------- -// Function wrappers around RL_*alloc macros, used by glfwInitAllocator() inside of InitPlatform() -// We need to provide these because GLFWallocator expects function pointers with specific signatures +// Function wrappers around RL_*ALLOC macros, used by glfwInitAllocator() inside of InitPlatform() +// GLFWallocator expects function pointers with specific signatures to be provided // REF: https://www.glfw.org/docs/latest/intro_guide.html#init_allocator static void *AllocateWrapper(size_t size, void *user) { @@ -1742,7 +1742,7 @@ int InitPlatform(void) for (int i = 0; i < MAX_GAMEPADS; i++) { // WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH, - // we can get a not-NULL terminated string, so, we only copy up to (MAX_GAMEPAD_NAME_LENGTH - 1) + // only copying up to (MAX_GAMEPAD_NAME_LENGTH - 1) if (glfwJoystickPresent(i)) { CORE.Input.Gamepad.ready[i] = true; @@ -1819,8 +1819,8 @@ static void FramebufferSizeCallback(GLFWwindow *window, int width, int height) { //TRACELOG(LOG_INFO, "GLFW3: Window framebuffer size callback called [%i,%i]", width, height); - // WARNING: On window minimization, callback is called, - // but we don't want to change internal screen values, it breaks things + // WARNING: On window minimization, callback is called with 0 values, + // but internal screen values should not be changed, it breaks things if ((width == 0) || (height == 0)) return; // Reset viewport and projection matrix for new size @@ -1926,7 +1926,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths { if (count > 0) { - // In case previous dropped filepaths have not been freed, we free them + // In case previous dropped filepaths have not been freed, free them if (CORE.Window.dropFileCount > 0) { for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]); @@ -1937,7 +1937,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths CORE.Window.dropFilepaths = NULL; } - // WARNING: Paths are freed by GLFW when the callback returns, we must keep an internal copy + // WARNING: Paths are freed by GLFW when the callback returns, keeping an internal copy CORE.Window.dropFileCount = count; CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *)); @@ -1954,7 +1954,7 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i { if (key < 0) return; // Security check, macOS fn key generates -1 - // WARNING: GLFW could return GLFW_REPEAT, we need to consider it as 1 + // WARNING: GLFW could return GLFW_REPEAT, it needs to be considered as 1 // to work properly with our implementation (IsKeyDown/IsKeyUp checks) if (action == GLFW_RELEASE) CORE.Input.Keyboard.currentKeyState[key] = 0; else if (action == GLFW_PRESS) CORE.Input.Keyboard.currentKeyState[key] = 1; @@ -2079,7 +2079,7 @@ static void JoystickCallback(int jid, int event) if (event == GLFW_CONNECTED) { // WARNING: If glfwGetJoystickName() is longer than MAX_GAMEPAD_NAME_LENGTH, - // we can get a not-NULL terminated string, so, we clean destination and only copy up to -1 + // only copy up to (MAX_GAMEPAD_NAME_LENGTH -1) to destination string memset(CORE.Input.Gamepad.name[jid], 0, MAX_GAMEPAD_NAME_LENGTH); strncpy(CORE.Input.Gamepad.name[jid], glfwGetJoystickName(jid), MAX_GAMEPAD_NAME_LENGTH - 1); } diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index eabea6bfe..66a917da2 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -49,7 +49,7 @@ #define USING_SDL3_PROJECT #endif #ifndef SDL_ENABLE_OLD_NAMES - #define SDL_ENABLE_OLD_NAMES // Just in case we're on SDL3, we need some in-between compatibily + #define SDL_ENABLE_OLD_NAMES // Just in case on SDL3, some in-between compatibily is needed #endif // SDL base library (window/rendered, input, timing... functionality) #ifdef USING_SDL3_PROJECT @@ -254,10 +254,10 @@ static const int CursorsLUT[] = { #if defined(USING_VERSION_SDL3) // SDL3 Migration: -// SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, -// and you can call SDL_GetWindowFullscreenMode() -// to see whether an exclusive fullscreen mode will be used -// or the borderless fullscreen desktop mode will be used +// SDL_WINDOW_FULLSCREEN_DESKTOP has been removed, +// and you can call SDL_GetWindowFullscreenMode() +// to see whether an exclusive fullscreen mode will be used +// or the borderless fullscreen desktop mode will be used #define SDL_WINDOW_FULLSCREEN_DESKTOP SDL_WINDOW_FULLSCREEN #define SDL_IGNORE false @@ -323,7 +323,7 @@ Uint8 SDL_EventState(Uint32 type, int state) return stateBefore; } -void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode* mode) +void SDL_GetCurrentDisplayMode_Adapter(SDL_DisplayID displayID, SDL_DisplayMode *mode) { const SDL_DisplayMode *currentMode = SDL_GetCurrentDisplayMode(displayID); @@ -340,9 +340,8 @@ SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth } // SDL3 Migration: -// SDL_GetDisplayDPI() - -// not reliable across platforms, approximately replaced by multiplying -// SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms +// SDL_GetDisplayDPI() not reliable across platforms, approximately replaced by multiplying +// SDL_GetWindowDisplayScale() times 160 on iPhone and Android, and 96 on other platforms // returns 0 on success or a negative error code on failure int SDL_GetDisplayDPI(int displayIndex, float *ddpi, float *hdpi, float *vdpi) { @@ -413,7 +412,7 @@ int SDL_GetNumTouchFingers(SDL_TouchID touchID) return count; } -#else // We're on SDL2 +#else // SDL2 fallback // Since SDL2 doesn't have this function we leave a stub // SDL_GetClipboardData function is available since SDL 3.1.3. (e.g. SDL3) @@ -833,10 +832,9 @@ void SetWindowMonitor(int monitor) if ((monitor >= 0) && (monitor < monitorCount)) #endif { - // NOTE: - // 1. SDL started supporting moving exclusive fullscreen windows between displays on SDL3, - // see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba - // 2. A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again + // NOTE 1: SDL started supporting moving exclusive fullscreen windows between displays on SDL3, + // see commit https://github.com/libsdl-org/SDL/commit/3f5ef7dd422057edbcf3e736107e34be4b75d9ba + // NOTE 2: A workaround for SDL2 is leaving fullscreen, moving the window, then entering full screen again const bool wasFullscreen = (FLAG_IS_SET(CORE.Window.flags, FLAG_FULLSCREEN_MODE))? true : false; const int screenWidth = CORE.Window.screen.width; @@ -854,14 +852,13 @@ void SetWindowMonitor(int monitor) // If the screen size is larger than the monitor usable area, anchor it on the top left corner, otherwise, center it if ((screenWidth >= usableBounds.w) || (screenHeight >= usableBounds.h)) { - // NOTE: - // 1. There's a known issue where if the window larger than the target display bounds, - // when moving the windows to that display, the window could be clipped back - // ending up positioned partly outside the target display - // 2. The workaround for that is, previously to moving the window, - // setting the window size to the target display size, so they match - // 3. It wasn't done here because we can't assume changing the window size automatically - // is acceptable behavior by the user + // NOTE 1: There's a known issue where if the window larger than the target display bounds, + // when moving the windows to that display, the window could be clipped back + // ending up positioned partly outside the target display + // NOTE 2: The workaround for that is, previously to moving the window, + // setting the window size to the target display size, so they match + // NOTE 3: It wasn't done here because we can't assume changing the window size automatically + // is acceptable behavior by the user SDL_SetWindowPosition(platform.window, usableBounds.x, usableBounds.y); CORE.Window.position.x = usableBounds.x; CORE.Window.position.y = usableBounds.y; @@ -1250,7 +1247,7 @@ void DisableCursor(void) void SwapScreenBuffer(void) { #if defined(GRAPHICS_API_OPENGL_11_SOFTWARE) - // NOTE: We use a preprocessor condition here because `rlCopyFramebuffer` is only declared for software rendering + // NOTE: We use a preprocessor condition here because rlCopyFramebuffer() is only declared for software rendering SDL_Surface *surface = SDL_GetWindowSurface(platform.window); rlCopyFramebuffer(0, 0, CORE.Window.render.width, CORE.Window.render.height, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, surface->pixels); SDL_UpdateWindowSurface(platform.window); @@ -1617,7 +1614,7 @@ void PollInputEvents(void) case SDL_MOUSEBUTTONDOWN: { // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW - // The following conditions align SDL with raylib.h MouseButton enum order + // The following conditions align SDL with raylib.h MouseButton enum order int btn = event.button.button - 1; if (btn == 2) btn = 1; else if (btn == 1) btn = 2; @@ -1630,7 +1627,7 @@ void PollInputEvents(void) case SDL_MOUSEBUTTONUP: { // NOTE: SDL2 mouse button order is LEFT, MIDDLE, RIGHT, but raylib uses LEFT, RIGHT, MIDDLE like GLFW - // The following conditions align SDL with raylib.h MouseButton enum order + // The following conditions align SDL with raylib.h MouseButton enum order int btn = event.button.button - 1; if (btn == 2) btn = 1; else if (btn == 1) btn = 2; diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 9f33dce1b..70ebd8b92 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -433,7 +433,7 @@ static bool UpdateWindowSize(int mode, HWND hwnd, int width, int height, unsigne return true; } -// Verify if we are running in Windows 10 version 1703 (Creators Update) +// Check if running in Windows 10 version 1703 (Creators Update) static BOOL IsWindows10Version1703OrGreaterWin32(void) { HMODULE ntdll = LoadLibraryW(L"ntdll.dll"); @@ -1138,7 +1138,7 @@ void ShowCursor(void) // Hides mouse cursor void HideCursor(void) { - // NOTE: We use SetCursor() instead of ShowCursor() because + // NOTE: Using SetCursor() instead of ShowCursor() because // it makes it easy to only hide the cursor while it's inside the client area SetCursor(NULL); CORE.Input.Mouse.cursorHidden = true; @@ -1227,7 +1227,7 @@ void SwapScreenBuffer(void) // Get elapsed time measure in seconds double GetTime(void) { - LARGE_INTEGER now = 0; + LARGE_INTEGER now = { 0 }; QueryPerformanceCounter(&now); return (double)(now.QuadPart - CORE.Time.base)/(double)platform.timerFrequency.QuadPart; } @@ -1345,7 +1345,7 @@ void PollInputEvents(void) //---------------------------------------------------------------------------------- // Initialize modern OpenGL context -// NOTE: We need to create a dummy context first to query required extensions +// NOTE: Creating a dummy context first to query required extensions HGLRC InitOpenGL(HWND hwnd, HDC hdc) { // First, create a dummy context to get WGL extensions @@ -1460,7 +1460,7 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc) 0 // Terminator }; - // NOTE: We are not sharing context resources so, second parameters is NULL + // NOTE: Not sharing context resources so, second parameters is NULL realContext = wglCreateContextAttribsARB(hdc, NULL, contextAttribs); // Check for error context creation errors @@ -1476,8 +1476,8 @@ HGLRC InitOpenGL(HWND hwnd, HDC hdc) // Activate real context if (realContext) wglMakeCurrent(hdc, realContext); - // Once we got a real modern OpenGL context, - // we can load required extensions (function pointers) + // Once a real modern OpenGL context is created, + // required extensions can be loaded (function pointers) rlLoadExtensions(WglGetProcAddress); return realContext; @@ -1521,7 +1521,7 @@ int InitPlatform(void) .lpfnWndProc = WndProc, // Custom procedure assigned .cbWndExtra = sizeof(LONG_PTR), // extra space for the Tuple object ptr .hInstance = hInstance, - .hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW), // TODO: Audit if we want to set this since we're implementing WM_SETCURSOR + .hCursor = LoadCursorW(NULL, (LPCWSTR)IDC_ARROW), // TODO: Check if this is really required, since WM_SETCURSOR event is processed .lpszClassName = CLASS_NAME // Class name: L"raylibWindow" }; @@ -1854,8 +1854,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara SIZE *inoutSize = (SIZE *)lparam; UINT newDpi = (UINT)wparam; // TODO: WARNING: Converting from WPARAM = UINT_PTR - // for any of these other cases, we might want to post a window - // resize event after the dpi changes? + // For the following flag changes, a window resize event should be posted, + // TODO: Should it be done after dpi changes? if (CORE.Window.flags & FLAG_WINDOW_MINIMIZED) return TRUE; if (CORE.Window.flags & FLAG_WINDOW_MAXIMIZED) return TRUE; if (CORE.Window.flags & FLAG_BORDERLESS_WINDOWED_MODE) return TRUE; @@ -1875,8 +1875,8 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara case WM_DPICHANGED: { // Get current dpi scale factor - float scalex = HIWORD(wParam)/96.0f; - float scaley = LOWORD(wParam)/96.0f; + float scalex = HIWORD(wparam)/96.0f; + float scaley = LOWORD(wparam)/96.0f; RECT *suggestedRect = (RECT *)lparam; @@ -2025,8 +2025,8 @@ static void HandleRawInput(LPARAM lparam) if (input.data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) TRACELOG(LOG_ERROR, "TODO: handle virtual desktop mouse inputs!"); - // Trick to keep the mouse position at 0,0 and instead move - // the previous position so we can still get a proper mouse delta + // Trick to keep the mouse position at (0,0) and instead move + // the previous position so a proper mouse delta can still be retrieved //CORE.Input.Mouse.previousPosition.x -= input.data.mouse.lLastX; //CORE.Input.Mouse.previousPosition.y -= input.data.mouse.lLastY; //if (CORE.Input.Mouse.currentPosition.x != 0) abort(); @@ -2138,12 +2138,12 @@ static unsigned SanitizeFlags(int mode, unsigned flags) // This design takes care of many odd corner cases. For example, if you want to restore // a window that was previously maximized AND minimized and you want to remove both these // flags, you actually need to call ShowWindow with SW_RESTORE twice. Another example is -// if you have a maximized window, if the undecorated flag is modified then we'd need to -// update the window style, but updating the style would mean the window size would change -// causing the window to lose its Maximized state which would mean we'd need to update the -// window size and then update the window style a second time to restore that maximized +// if you have a maximized window, if the undecorated flag is modified then the window style +// needs to be updated, but updating the style would mean the window size would change +// causing the window to lose its Maximized state which would mean the window size +// needs to be updated, followed by the update of window style, a second time, to restore that maximized // state. This implementation is able to handle any/all of these special situations with a -// retry loop that continues until we either reach the desired state or the state stops changing +// retry loop that continues until either the desired state is reached or the state stops changing static void UpdateFlags(HWND hwnd, unsigned desiredFlags, int width, int height) { // Flags that just apply immediately without needing any operations diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index b296e0042..68431030b 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -915,7 +915,7 @@ void SwapScreenBuffer(void) { TRACELOG(LOG_ERROR, "DISPLAY: Failed to get DRM resources"); drmModeRmFB(platform.fd, fb); - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = creq.handle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); return; @@ -955,7 +955,7 @@ void SwapScreenBuffer(void) { TRACELOG(LOG_ERROR, "DISPLAY: No compatible CRTC found"); drmModeRmFB(platform.fd, fb); - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = creq.handle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); return; @@ -971,7 +971,7 @@ void SwapScreenBuffer(void) TRACELOG(LOG_ERROR, "DISPLAY: Mode: %dx%d@%d", mode->hdisplay, mode->vdisplay, mode->vrefresh); drmModeRmFB(platform.fd, fb); - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = creq.handle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); return; @@ -989,7 +989,7 @@ void SwapScreenBuffer(void) // Clean up previous dumb buffer if (platform.prevDumbHandle) { - struct drm_mode_destroy_dumb dreq = {0}; + struct drm_mode_destroy_dumb dreq = { 0 }; dreq.handle = platform.prevDumbHandle; drmIoctl(platform.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); } diff --git a/src/platforms/rcore_memory.c b/src/platforms/rcore_memory.c index c9409a750..1d69f5ed3 100644 --- a/src/platforms/rcore_memory.c +++ b/src/platforms/rcore_memory.c @@ -499,7 +499,7 @@ int InitPlatform(void) } //---------------------------------------------------------------------------- - // If everything work as expected, we can continue + // If everything worked as expected, continue CORE.Window.render.width = CORE.Window.screen.width; CORE.Window.render.height = CORE.Window.screen.height; CORE.Window.currentFbo.width = CORE.Window.render.width; diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index f1922600f..986197b9d 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -316,15 +316,16 @@ void ToggleBorderlessWindowed(void) // 2. The style unset handles the possibility of a width="value%" like on the default shell.html file EM_ASM ( + const canvasId = UTF8ToString($0); setTimeout(function() { Module.requestFullscreen(false, true); setTimeout(function() { - canvas.style.width="unset"; + document.querySelector(canvasId).style.width="unset"; }, 100); }, 100); - ); + , platform.canvasId); FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } } @@ -953,8 +954,8 @@ void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float d if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME; duration *= 1000.0f; // Convert duration to ms - // Note: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API, - // and Firefox only supports the hapticActuators API + // NOTE: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API, + // and Firefox only supports the hapticActuators API EM_ASM({ try { @@ -1238,9 +1239,9 @@ int InitPlatform(void) // Avoid creating a WebGL canvas, avoid calling glfwCreateWindow() emscripten_set_canvas_element_size(platform.canvasId, CORE.Window.screen.width, CORE.Window.screen.height); EM_ASM({ - const canvas = document.getElementById("canvas"); + const canvas = document.querySelector(UTF8ToString($0)); Module.canvas = canvas; - }); + }, platform.canvasId); // Load memory framebuffer with desired screen size // NOTE: Despite using a software framebuffer for blitting, GLFW still creates a WebGL canvas, @@ -1798,8 +1799,8 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent // Emscripten: Called on fullscreen change events static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData) { - // NOTE: 1. Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key - // 2. Which is a necessary safeguard because that case will bypass the toggles CORE.Window.flags resets + // NOTE 1: Reset the fullscreen flags if the user left fullscreen manually by pressing the Escape key + // NOTE 2: Which is a necessary safeguard because that case will bypass the toggles CORE.Window.flags resets if (platform.ourFullscreen) platform.ourFullscreen = false; else { diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 36b8e964a..ba2489a31 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -137,7 +137,7 @@ bool WindowShouldClose(void) // and encapsulating one frame execution on a UpdateDrawFrame() function, // allowing the browser to manage execution asynchronously - // Optionally we can manage the time we give-control-back-to-browser if required, + // NOTE: Optionally, time can be managed, giving control back-to-browser as required, // but it seems below line could generate stuttering on some browsers emscripten_sleep(12); @@ -280,15 +280,16 @@ void ToggleBorderlessWindowed(void) // 2. The style unset handles the possibility of a width="value%" like on the default shell.html file EM_ASM ( + const canvasId = UTF8ToString($0); setTimeout(function() { Module.requestFullscreen(false, true); setTimeout(function() { - canvas.style.width="unset"; + document.querySelector(canvasId).style.width="unset"; }, 100); }, 100); - ); + , platform.canvasId); FLAG_SET(CORE.Window.flags, FLAG_BORDERLESS_WINDOWED_MODE); } } @@ -1358,7 +1359,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths { if (count > 0) { - // In case previous dropped filepaths have not been freed, we free them + // In case previous dropped filepaths have not been freed, free them if (CORE.Window.dropFileCount > 0) { for (unsigned int i = 0; i < CORE.Window.dropFileCount; i++) RL_FREE(CORE.Window.dropFilepaths[i]); @@ -1369,7 +1370,7 @@ static void WindowDropCallback(GLFWwindow *window, int count, const char **paths CORE.Window.dropFilepaths = NULL; } - // WARNING: Paths are freed by GLFW when the callback returns, we must keep an internal copy + // WARNING: Paths are freed by GLFW when the callback returns, an internal copy should be kept CORE.Window.dropFileCount = count; CORE.Window.dropFilepaths = (char **)RL_CALLOC(CORE.Window.dropFileCount, sizeof(char *)); @@ -1610,7 +1611,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent double canvasWidth = 0.0; double canvasHeight = 0.0; // NOTE: emscripten_get_canvas_element_size() returns canvas.width and canvas.height but - // we are looking for actual CSS size: canvas.style.width and canvas.style.height + // looking for actual CSS size: canvas.style.width and canvas.style.height // EMSCRIPTEN_RESULT res = emscripten_get_canvas_element_size("#canvas", &canvasWidth, &canvasHeight); emscripten_get_element_css_size(platform.canvasId, &canvasWidth, &canvasHeight); @@ -1630,7 +1631,7 @@ static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) CORE.Input.Touch.currentTouchState[i] = 0; } - // Update mouse position if we detect a single touch + // Update mouse position if a single touch is detected if (CORE.Input.Touch.pointCount == 1) { CORE.Input.Mouse.currentPosition.x = CORE.Input.Touch.position[0].x; diff --git a/src/raudio.c b/src/raudio.c index 18f9e0aad..2e087205e 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -2418,7 +2418,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, audioBuffer->frameCursorPos = (audioBuffer->frameCursorPos + framesToRead)%audioBuffer->sizeInFrames; framesRead += framesToRead; - // If we've read to the end of the buffer, mark it as processed + // If the end of the buffer is read, mark it as processed if (framesToRead == framesRemainingInOutputBuffer) { audioBuffer->isSubBufferProcessed[currentSubBufferIndex] = true; @@ -2426,7 +2426,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, currentSubBufferIndex = (currentSubBufferIndex + 1)%2; - // We need to break from this loop if we're not looping + // Break from this loop if looping not enabled if (!audioBuffer->looping) { StopAudioBufferInLockedState(audioBuffer); @@ -2453,10 +2453,12 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, // Reads audio data from an AudioBuffer object in device format, returned data will be in a format appropriate for mixing static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount) { - // What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which - // should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important - // 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() + // NOTE: Continuously converting data from the AudioBuffer's internal format to the mixing format, + // which should be defined by the output format of the data converter. + // This is done until frameCount frames have been output. + // The important detail to remember is that more data than required should neeveer be read, + // 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.formatIn, audioBuffer->converter.channelsIn); @@ -2573,8 +2575,8 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const } } - // If for some reason we weren't able to read every frame we'll need to break from the loop - // Not doing this could theoretically put us into an infinite loop + // If for some reason is not possible to read every frame, the loop needs to be broken + // Not doing this could theoretically eend up into an infinite loop if (framesToRead > 0) break; } } diff --git a/src/raylib.h b/src/raylib.h index 177138dc9..8a0a14dad 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -336,7 +336,7 @@ typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D typedef struct Camera2D { Vector2 offset; // Camera offset (screen space offset from window origin) Vector2 target; // Camera target (world space target point that is mapped to screen space offset) - float rotation; // Camera rotation in degrees (pivots around target) + float rotation; // Camera rotation in degrees (pivots around target) float zoom; // Camera zoom (scaling around target), must not be set to 0, set to 1.0f for no scale } Camera2D; @@ -512,7 +512,6 @@ typedef struct VrStereoConfig { // File path list typedef struct FilePathList { - unsigned int capacity; // Filepaths max entries unsigned int count; // Filepaths entries count char **paths; // Filepaths entries } FilePathList; @@ -1152,6 +1151,8 @@ RLAPI void UnloadDirectoryFiles(FilePathList files); // Unload fi RLAPI bool IsFileDropped(void); // Check if a file has been dropped into window RLAPI FilePathList LoadDroppedFiles(void); // Load dropped filepaths RLAPI void UnloadDroppedFiles(FilePathList files); // Unload dropped filepaths +RLAPI unsigned int GetDirectoryFileCount(const char *dirPath); // Get the file count in a directory +RLAPI unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, bool scanSubdirs);// Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result // Compression/Encoding functionality RLAPI unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); // Compress data (DEFLATE algorithm), memory must be MemFree() diff --git a/src/raymath.h b/src/raymath.h index 57e3dac51..0f9cbc38b 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -66,11 +66,11 @@ // Function specifiers definition #if defined(RAYMATH_IMPLEMENTATION) #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) - #define RMAPI __declspec(dllexport) extern inline // We are building raylib as a Win32 shared library (.dll) + #define RMAPI __declspec(dllexport) extern inline // Building raylib as a Win32 shared library (.dll) #elif defined(BUILD_LIBTYPE_SHARED) - #define RMAPI __attribute__((visibility("default"))) // We are building raylib as a Unix shared library (.so/.dylib) + #define RMAPI __attribute__((visibility("default"))) // Building raylib as a Unix shared library (.so/.dylib) #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) - #define RMAPI __declspec(dllimport) // We are using raylib as a Win32 shared library (.dll) + #define RMAPI __declspec(dllimport) // Using raylib as a Win32 shared library (.dll) #else #define RMAPI extern inline // Provide external definition #endif @@ -595,7 +595,7 @@ RMAPI int Vector2Equals(Vector2 p, Vector2 q) // v: normalized direction of the incoming ray // n: normalized normal vector of the interface of two optical media // r: 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 +// to the refractive index of the medium on the other side of the surface RMAPI Vector2 Vector2Refract(Vector2 v, Vector2 n, float r) { Vector2 result = { 0 }; @@ -1083,7 +1083,7 @@ RMAPI Vector3 Vector3Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c) } // Projects a Vector3 from screen space into object space -// NOTE: We are avoiding calling other raymath functions despite available +// NOTE: Self-contained function, no other raymath functions are called RMAPI Vector3 Vector3Unproject(Vector3 source, Matrix projection, Matrix view) { Vector3 result = { 0 }; @@ -1245,7 +1245,7 @@ RMAPI int Vector3Equals(Vector3 p, Vector3 q) // v: normalized direction of the incoming ray // n: normalized normal vector of the interface of two optical media // r: 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 +// 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 }; @@ -2363,13 +2363,13 @@ RMAPI Quaternion QuaternionFromVector3ToVector3(Vector3 from, Vector3 to) { Quaternion result = { 0 }; - float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to) + float cos2Theta = (from.x*to.x + from.y*to.y + from.z*to.z); // Vector3DotProduct(from, to) Vector3 cross = { from.y*to.z - from.z*to.y, from.z*to.x - from.x*to.z, from.x*to.y - from.y*to.x }; // Vector3CrossProduct(from, to) result.x = cross.x; result.y = cross.y; result.z = cross.z; - result.w = 1.0f + cos2Theta; + result.w = sqrtf(cross.x*cross.x + cross.y*cross.y + cross.z*cross.z + cos2Theta*cos2Theta) + cos2Theta; // QuaternionNormalize(q); // NOTE: Normalize to essentially nlerp the original and identity to 0.5 @@ -2663,14 +2663,14 @@ RMAPI Matrix MatrixCompose(Vector3 translation, Quaternion rotation, Vector3 sca forward = Vector3RotateByQuaternion(forward, rotation); // Set result matrix output - Matrix result = { - right.x, up.x, forward.x, translation.x, - right.y, up.y, forward.y, translation.y, - right.z, up.z, forward.z, translation.z, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix result = { + right.x, up.x, forward.x, translation.x, + right.y, up.y, forward.y, translation.y, + right.z, up.z, forward.z, translation.z, + 0.0f, 0.0f, 0.0f, 1.0f + }; - return result; + return result; } // Decompose a transformation matrix into its rotational, translational and scaling components and remove shear diff --git a/src/rcore.c b/src/rcore.c index 1794637bd..810915040 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -267,9 +267,15 @@ #define MAX_AUTOMATION_EVENTS 16384 // Maximum number of automation events to record #endif -#ifndef DIRECTORY_FILTER_TAG - #define DIRECTORY_FILTER_TAG "DIR" // Name tag used to request directory inclusion on directory scan -#endif // NOTE: Used in ScanDirectoryFiles(), ScanDirectoryFilesRecursively() and LoadDirectoryFilesEx() +#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() +#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() +#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() // Flags operation macros #define FLAG_SET(n, f) ((n) |= (f)) @@ -505,8 +511,7 @@ extern void ClosePlatform(void); // Close platform static void InitTimer(void); // Initialize timer, hi-resolution if available (required by InitPlatform()) static void SetupViewport(int width, int height); // Set viewport for a provided width and height -static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories in a base path -static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *list, const char *filter); // Scan all files and directories recursively from a base path +static void ScanDirectoryFiles(const char *basePath, FilePathList *list, const char *filter, unsigned int expectedFileCount, bool scanSubdirs); // Scan all files and directories in a base path #if defined(SUPPORT_AUTOMATION_EVENTS) static void RecordAutomationEvent(void); // Record frame events (to internal events array) @@ -525,7 +530,7 @@ const char *TextFormat(const char *text, ...); // Formatting of text with variab #define PLATFORM_DESKTOP_GLFW #endif -// We're using '#pragma message' because '#warning' is not adopted by MSVC +// Using '#pragma message' because '#warning' is not adopted by MSVC #if defined(SUPPORT_CLIPBOARD_IMAGE) #if !defined(SUPPORT_MODULE_RTEXTURES) #pragma message ("WARNING: Enabling SUPPORT_CLIPBOARD_IMAGE requires SUPPORT_MODULE_RTEXTURES to work properly") @@ -1499,7 +1504,7 @@ Matrix GetCameraMatrix2D(Camera2D camera) // When setting higher scale, it's more intuitive for the world to become bigger (= camera become smaller), // not for the camera getting bigger, hence the invert. Same deal with rotation // 3. Move it by (-offset); - // Offset defines target transform relative to screen, but since we're effectively "moving" screen (camera) + // Offset defines target transform relative to screen, but since effectively "moving" screen (camera) // we need to do it into opposite direction (inverse transform) // Having camera transform in world-space, inverse of it gives the modelview transform @@ -1931,7 +1936,7 @@ void TraceLog(int logType, const char *text, ...) // Set custom trace log void SetTraceLogCallback(TraceLogCallback callback) -{ +{ traceLog = callback; } @@ -2753,53 +2758,36 @@ const char *GetApplicationDirectory(void) // No recursive scanning is done! FilePathList LoadDirectoryFiles(const char *dirPath) { - FilePathList files = { 0 }; - unsigned int fileCounter = 0; - - struct dirent *entity; - DIR *dir = opendir(dirPath); - - if (dir != NULL) // It's a directory - { - // SCAN 1: Count files - while ((entity = readdir(dir)) != NULL) - { - // NOTE: We skip '.' (current dir) and '..' (parent dir) filepaths - if ((strcmp(entity->d_name, ".") != 0) && (strcmp(entity->d_name, "..") != 0)) fileCounter++; - } - - // Memory allocation for dirFileCount - files.capacity = fileCounter; - files.paths = (char **)RL_CALLOC(files.capacity, sizeof(char *)); - for (unsigned int i = 0; i < files.capacity; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); - - closedir(dir); - - // SCAN 2: Read filepaths - // NOTE: Directory paths are also registered - ScanDirectoryFiles(dirPath, &files, NULL); - - // Security check: read files.count should match fileCounter - if (files.count != files.capacity) TRACELOG(LOG_WARNING, "FILEIO: Read files count do not match capacity allocated"); - } - else TRACELOG(LOG_WARNING, "FILEIO: Failed to open requested directory"); // Maybe it's a file... - - return files; + return LoadDirectoryFilesEx(dirPath, FILE_FILTER_TAG_ALL, false); } // Load directory filepaths with extension filtering and recursive directory scan -// NOTE: On recursive loading we do not pre-scan for file count, we use MAX_FILEPATH_CAPACITY +// WARNING: Directory is scanned twice, first time to get files count FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs) { FilePathList files = { 0 }; - files.capacity = MAX_FILEPATH_CAPACITY; - files.paths = (char **)RL_CALLOC(files.capacity, sizeof(char *)); - for (unsigned int i = 0; i < files.capacity; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + if (DirectoryExists(basePath)) // It's a directory + { + // SCAN 1: Count files + unsigned int fileCounter = GetDirectoryFileCountEx(basePath, filter, scanSubdirs); - // WARNING: basePath is always prepended to scanned paths - if (scanSubdirs) ScanDirectoryFilesRecursively(basePath, &files, filter); - else ScanDirectoryFiles(basePath, &files, filter); + // Memory allocation for dirFileCount + files.paths = (char **)RL_CALLOC(fileCounter, sizeof(char *)); + for (unsigned int i = 0; i < fileCounter; i++) files.paths[i] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); + + // SCAN 2: Read filepaths + // WARNING: basePath is always prepended to scanned paths + ScanDirectoryFiles(basePath, &files, filter, fileCounter, scanSubdirs); + + // Security check: read files.count should match fileCounter + if (files.count != fileCounter) + { + TRACELOG(LOG_WARNING, "FILEIO: Read files count (%u) does not match capacity allocated (%u)", files.count, fileCounter); + files.count = fileCounter; // Avoid memory leak when unloading this FilePathList + } + } + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... return files; } @@ -2810,7 +2798,7 @@ void UnloadDirectoryFiles(FilePathList files) { if (files.paths != NULL) { - for (unsigned int i = 0; i < files.capacity; i++) RL_FREE(files.paths[i]); + for (unsigned int i = 0; i < files.count; i++) RL_FREE(files.paths[i]); RL_FREE(files.paths); } @@ -2966,6 +2954,59 @@ void UnloadDroppedFiles(FilePathList files) } } +// Get the file count in a directory +unsigned int GetDirectoryFileCount(const char *dirPath) +{ + return GetDirectoryFileCountEx(dirPath, FILE_FILTER_TAG_ALL, false); +} + +// Get the file count in a directory with extension filtering and recursive directory scan. Use 'FILE_FILTER_TAG_DIR_ONLY' in the filter string to include directories in the result +unsigned int GetDirectoryFileCountEx(const char *basePath, const char *filter, bool scanSubdirs) +{ + unsigned int fileCounter = 0; + + // WARNING: Path can not be static or it will be reused between recursive function calls! + char path[MAX_FILEPATH_LENGTH] = { 0 }; + memset(path, 0, MAX_FILEPATH_LENGTH); + + struct dirent *entity; + DIR *dir = opendir(basePath); + + if (dir != NULL) // It's a directory + { + while ((entity = readdir(dir)) != NULL) + { + // NOTE: We skip '.' (current dir) and '..' (parent dir) filepaths + if ((strcmp(entity->d_name, ".") != 0) && (strcmp(entity->d_name, "..") != 0)) + { + // Construct new path from our base path + #if defined(_WIN32) + int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, entity->d_name); + #else + int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, entity->d_name); + #endif + // Don't add to count if path too long + if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH)) + { + TRACELOG(LOG_WARNING, "FILEIO: Path longer than %d characters (%s...)", MAX_FILEPATH_LENGTH, basePath); + } + else if (IsPathFile(path)) + { + if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || + (strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter)) fileCounter++; + } + else + { + if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || (strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL))) fileCounter++; + if (scanSubdirs) fileCounter += GetDirectoryFileCountEx(path, filter, scanSubdirs); + } + } + } + } + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... + return fileCounter; +} + //---------------------------------------------------------------------------------- // Module Functions Definition: Compression and Encoding //---------------------------------------------------------------------------------- @@ -3629,13 +3670,13 @@ bool ExportAutomationEventList(AutomationEventList list, const char *fileName) int binarySize = 4 + sizeof(int) + sizeof(AutomationEvent)*list.count; unsigned char *binBuffer = (unsigned char *)RL_CALLOC(binarySize, 1); int offset = 0; - memcpy(binBuffer + offset, "rAE ", 4); + memcpy(binBuffer + offset, "rAE ", 4); offset += 4; - memcpy(binBuffer + offset, &list.count, sizeof(int)); + memcpy(binBuffer + offset, &list.count, sizeof(int)); offset += sizeof(int); memcpy(binBuffer + offset, list.events, sizeof(AutomationEvent)*list.count); offset += sizeof(AutomationEvent)*list.count; - + success = SaveFileData(TextFormat("%s.rae",fileName), binBuffer, binarySize); RL_FREE(binBuffer); } @@ -3790,7 +3831,6 @@ void PlayAutomationEvent(AutomationEvent event) // Check if a key has been pressed once bool IsKeyPressed(int key) { - bool pressed = false; if ((key > 0) && (key < MAX_KEYBOARD_KEYS)) @@ -3932,8 +3972,10 @@ bool IsGamepadButtonPressed(int gamepad, int button) { bool pressed = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.previousButtonState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) pressed = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 0) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) pressed = true; + } return pressed; } @@ -3943,8 +3985,10 @@ bool IsGamepadButtonDown(int gamepad, int button) { bool down = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1)) down = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 1) down = true; + } return down; } @@ -3954,8 +3998,10 @@ bool IsGamepadButtonReleased(int gamepad, int button) { bool released = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.previousButtonState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) released = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if ((CORE.Input.Gamepad.previousButtonState[gamepad][button] == 1) && (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) released = true; + } return released; } @@ -3965,13 +4011,16 @@ bool IsGamepadButtonUp(int gamepad, int button) { bool up = false; - if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS) && - (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0)) up = true; + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (button < MAX_GAMEPAD_BUTTONS)) + { + if (CORE.Input.Gamepad.currentButtonState[gamepad][button] == 0) up = true; + } return up; } // Get the last gamepad button pressed +// NOTE: Returns last gamepad button down, down->up change not considered int GetGamepadButtonPressed(void) { return CORE.Input.Gamepad.lastButtonPressed; @@ -4011,10 +4060,13 @@ bool IsMouseButtonPressed(int button) { bool pressed = false; - if ((CORE.Input.Mouse.currentButtonState[button] == 1) && (CORE.Input.Mouse.previousButtonState[button] == 0)) pressed = true; + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + if ((CORE.Input.Mouse.currentButtonState[button] == 1) && (CORE.Input.Mouse.previousButtonState[button] == 0)) pressed = true; - // Map touches to mouse buttons checking - if ((CORE.Input.Touch.currentTouchState[button] == 1) && (CORE.Input.Touch.previousTouchState[button] == 0)) pressed = true; + // Map touches to mouse buttons checking + if ((CORE.Input.Touch.currentTouchState[button] == 1) && (CORE.Input.Touch.previousTouchState[button] == 0)) pressed = true; + } return pressed; } @@ -4024,10 +4076,13 @@ bool IsMouseButtonDown(int button) { bool down = false; - if (CORE.Input.Mouse.currentButtonState[button] == 1) down = true; + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + if (CORE.Input.Mouse.currentButtonState[button] == 1) down = true; - // NOTE: Touches are considered like mouse buttons - if (CORE.Input.Touch.currentTouchState[button] == 1) down = true; + // NOTE: Touches are considered like mouse buttons + if (CORE.Input.Touch.currentTouchState[button] == 1) down = true; + } return down; } @@ -4037,10 +4092,13 @@ bool IsMouseButtonReleased(int button) { bool released = false; - if ((CORE.Input.Mouse.currentButtonState[button] == 0) && (CORE.Input.Mouse.previousButtonState[button] == 1)) released = true; + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + if ((CORE.Input.Mouse.currentButtonState[button] == 0) && (CORE.Input.Mouse.previousButtonState[button] == 1)) released = true; - // Map touches to mouse buttons checking - if ((CORE.Input.Touch.currentTouchState[button] == 0) && (CORE.Input.Touch.previousTouchState[button] == 1)) released = true; + // Map touches to mouse buttons checking + if ((CORE.Input.Touch.currentTouchState[button] == 0) && (CORE.Input.Touch.previousTouchState[button] == 1)) released = true; + } return released; } @@ -4050,10 +4108,13 @@ bool IsMouseButtonUp(int button) { bool up = false; - if (CORE.Input.Mouse.currentButtonState[button] == 0) up = true; + if ((button >= 0) && (button <= MOUSE_BUTTON_BACK)) + { + if (CORE.Input.Mouse.currentButtonState[button] == 0) up = true; - // NOTE: Touches are considered like mouse buttons - if (CORE.Input.Touch.currentTouchState[button] == 0) up = true; + // NOTE: Touches are considered like mouse buttons + if (CORE.Input.Touch.currentTouchState[button] == 0) up = true; + } return up; } @@ -4062,6 +4123,7 @@ bool IsMouseButtonUp(int button) int GetMouseX(void) { int mouseX = (int)((CORE.Input.Mouse.currentPosition.x + CORE.Input.Mouse.offset.x)*CORE.Input.Mouse.scale.x); + return mouseX; } @@ -4069,6 +4131,7 @@ int GetMouseX(void) int GetMouseY(void) { int mouseY = (int)((CORE.Input.Mouse.currentPosition.y + CORE.Input.Mouse.offset.y)*CORE.Input.Mouse.scale.y); + return mouseY; } @@ -4229,66 +4292,7 @@ void SetupViewport(int width, int height) // Scan all files and directories in a base path // WARNING: files.paths[] must be previously allocated and // contain enough space to store all required paths -static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const char *filter) -{ - static char path[MAX_FILEPATH_LENGTH] = { 0 }; - memset(path, 0, MAX_FILEPATH_LENGTH); - - struct dirent *dp = NULL; - DIR *dir = opendir(basePath); - - if (dir != NULL) - { - while ((dp = readdir(dir)) != NULL) - { - if ((strcmp(dp->d_name, ".") != 0) && - (strcmp(dp->d_name, "..") != 0)) - { - // Construct new path from our base path - #if defined(_WIN32) - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s\\%s", basePath, dp->d_name); - #else - int pathLength = snprintf(path, MAX_FILEPATH_LENGTH - 1, "%s/%s", basePath, dp->d_name); - #endif - - if ((pathLength < 0) || (pathLength >= MAX_FILEPATH_LENGTH)) - { - TRACELOG(LOG_WARNING, "FILEIO: Path longer than %d characters (%s...)", MAX_FILEPATH_LENGTH, basePath); - } - else if (filter != NULL) - { - if (IsPathFile(path)) - { - if (IsFileExtension(path, filter)) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - else - { - if (strstr(filter, DIRECTORY_FILTER_TAG) != NULL) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - } - else - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - } - - closedir(dir); - } - else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); -} - -// Scan all files and directories recursively from a base path -static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *files, const char *filter) +static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const char *filter, unsigned int expectedFileCount, bool scanSubdirs) { // WARNING: Path can not be static or it will be reused between recursive function calls! char path[MAX_FILEPATH_LENGTH] = { 0 }; @@ -4299,7 +4303,7 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi if (dir != NULL) { - while (((dp = readdir(dir)) != NULL) && (files->count < files->capacity)) + while (((dp = readdir(dir)) != NULL) && (files->count < expectedFileCount)) { if ((strcmp(dp->d_name, ".") != 0) && (strcmp(dp->d_name, "..") != 0)) { @@ -4316,48 +4320,29 @@ static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *fi } else if (IsPathFile(path)) { - if (filter != NULL) - { - if (IsFileExtension(path, filter)) - { - strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); - files->count++; - } - } - else + if ((filter == NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL) || + (strstr(filter, FILE_FILTER_TAG_FILE_ONLY) != NULL) || IsFileExtension(path, filter)) { strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } - - if (files->count >= files->capacity) - { - TRACELOG(LOG_WARNING, "FILEIO: Maximum filepath scan capacity reached (%i files)", files->capacity); - break; - } } else { - if ((filter != NULL) && (strstr(filter, DIRECTORY_FILTER_TAG) != NULL)) + if ((filter != NULL) && ((strstr(filter, FILE_FILTER_TAG_DIR_ONLY) != NULL) || (strstr(filter, FILE_FILTER_TAG_ALL) != NULL))) { strncpy(files->paths[files->count], path, MAX_FILEPATH_LENGTH - 1); files->count++; } - if (files->count >= files->capacity) - { - TRACELOG(LOG_WARNING, "FILEIO: Maximum filepath scan capacity reached (%i files)", files->capacity); - break; - } - - ScanDirectoryFilesRecursively(path, files, filter); + if (scanSubdirs) ScanDirectoryFiles(path, files, filter, expectedFileCount, scanSubdirs); } } } closedir(dir); } - else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); + else TRACELOG(LOG_WARNING, "FILEIO: Directory cannot be opened (%s)", basePath); // Maybe it's a file... } #if defined(SUPPORT_AUTOMATION_EVENTS) @@ -4506,7 +4491,7 @@ static void RecordAutomationEvent(void) if (currentEventList->count == currentEventList->capacity) return; // Security check - // Event type: INPUT_TOUCH_POSITION + // Event type: INPUT_TOUCH_POSITION if (((int)CORE.Input.Touch.position[id].x != (int)CORE.Input.Touch.previousPosition[id].x) || ((int)CORE.Input.Touch.position[id].y != (int)CORE.Input.Touch.previousPosition[id].y)) { @@ -4519,7 +4504,7 @@ static void RecordAutomationEvent(void) TRACELOG(LOG_INFO, "AUTOMATION: Frame: %i | Event type: INPUT_TOUCH_POSITION | Event parameters: %i, %i, %i", currentEventList->events[currentEventList->count].frame, currentEventList->events[currentEventList->count].params[0], currentEventList->events[currentEventList->count].params[1], currentEventList->events[currentEventList->count].params[2]); currentEventList->count++; } - + if (currentEventList->count == currentEventList->capacity) return; // Security check } diff --git a/src/rlgl.h b/src/rlgl.h index 8b264343a..d3e86cf1f 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -113,11 +113,11 @@ // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll // NOTE: visibility(default) attribute makes symbols "visible" when compiled with -fvisibility=hidden #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) - #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll) + #define RLAPI __declspec(dllexport) // Building the library as a Win32 shared library (.dll) #elif defined(BUILD_LIBTYPE_SHARED) - #define RLAPI __attribute__((visibility("default"))) // We are building the library as a Unix shared library (.so/.dylib) + #define RLAPI __attribute__((visibility("default"))) // Building the library as a Unix shared library (.so/.dylib) #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) - #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll) + #define RLAPI __declspec(dllimport) // Using the library as a Win32 shared library (.dll) #endif // Function specifiers definition @@ -1270,12 +1270,12 @@ void rlLoadIdentity(void) // Multiply the current matrix by a translation matrix void rlTranslatef(float x, float y, float z) { - Matrix matTranslation = { - 1.0f, 0.0f, 0.0f, x, - 0.0f, 1.0f, 0.0f, y, - 0.0f, 0.0f, 1.0f, z, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matTranslation = rlMatrixIdentity(); + + // Set translation component of matrix + matTranslation.m12 = x; + matTranslation.m13 = y; + matTranslation.m14 = z; // NOTE: We transpose matrix with multiplication order *RLGL.State.currentMatrix = rlMatrixMultiply(matTranslation, *RLGL.State.currentMatrix); @@ -1329,12 +1329,12 @@ void rlRotatef(float angle, float x, float y, float z) // Multiply the current matrix by a scaling matrix void rlScalef(float x, float y, float z) { - Matrix matScale = { - x, 0.0f, 0.0f, 0.0f, - 0.0f, y, 0.0f, 0.0f, - 0.0f, 0.0f, z, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matScale = rlMatrixIdentity(); + + // Set scale component of matrix + matScale.m0 = x; + matScale.m5 = y; + matScale.m10 = z; // NOTE: We transpose matrix with multiplication order *RLGL.State.currentMatrix = rlMatrixMultiply(matScale, *RLGL.State.currentMatrix); @@ -1344,6 +1344,7 @@ void rlScalef(float x, float y, float z) void rlMultMatrixf(const float *matf) { // Matrix creation from array + // Conversion from column-major to row-major memory order Matrix mat = { matf[0], matf[4], matf[8], matf[12], matf[1], matf[5], matf[9], matf[13], matf[2], matf[6], matf[10], matf[14], @@ -3731,7 +3732,7 @@ void *rlReadTexturePixels(unsigned int id, int width, int height, int format) // Two possible Options: // 1 - Bind texture to color fbo attachment and glReadPixels() // 2 - Create an fbo, activate it, render quad with texture, glReadPixels() - // We are using Option 1, just need to care for texture format on retrieval + // Using Option 1, just need to care for texture format on retrieval // NOTE: This behaviour could be conditioned by graphic driver... unsigned int fboId = rlLoadFramebuffer(); @@ -4463,13 +4464,7 @@ void rlSetVertexAttributeDefault(int locIndex, const void *value, int attribType void rlSetUniformMatrix(int locIndex, Matrix mat) { #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) - float matfloat[16] = { - mat.m0, mat.m1, mat.m2, mat.m3, - mat.m4, mat.m5, mat.m6, mat.m7, - mat.m8, mat.m9, mat.m10, mat.m11, - mat.m12, mat.m13, mat.m14, mat.m15 - }; - glUniformMatrix4fv(locIndex, 1, false, matfloat); + glUniformMatrix4fv(locIndex, 1, false, rlMatrixToFloat(mat)); #endif } @@ -5255,17 +5250,17 @@ static int rlGetPixelDataSize(int width, int height, int format) // Get identity matrix static Matrix rlMatrixIdentity(void) { - Matrix result = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f - }; + Matrix matIdentity = { 0 }; + matIdentity.m0 = 1.0f; + matIdentity.m5 = 1.0f; + matIdentity.m10 = 1.0f; + matIdentity.m15 = 1.0f; - return result; + return matIdentity; } #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Get float array of matrix data +// Explicit conversion to column-major memory layout static rl_float16 rlMatrixToFloatV(Matrix mat) { rl_float16 result = { 0 }; diff --git a/src/rmodels.c b/src/rmodels.c index 58b08350d..2988dfaba 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -1754,7 +1754,7 @@ void DrawMeshInstanced(Mesh mesh, Material material, const Matrix *transforms, i // This could alternatively use a static VBO and either glMapBuffer() or glBufferSubData() // It isn't clear which would be reliably faster in all cases and on all platforms, // anecdotally glMapBuffer() seems very slow (syncs) while glBufferSubData() seems - // no faster, since we're transferring all the transform matrices anyway + // no faster, since all the transform matrices are transferred anyway instancesVboId = rlLoadVertexBuffer(instanceTransforms, instances*sizeof(float16), false); // Instances transformation matrices are sent to shader attribute location: SHADER_LOC_VERTEX_INSTANCE_TX @@ -4084,7 +4084,7 @@ RayCollision GetRayCollisionBox(Ray ray, BoundingBox box) { RayCollision collision = { 0 }; - // Note: If ray.position is inside the box, the distance is negative (as if the ray was reversed) + // NOTE: If ray.position is inside the box, the distance is negative (as if the ray was reversed) // Reversing ray.direction will give use the correct result bool insideBox = (ray.position.x > box.min.x) && (ray.position.x < box.max.x) && (ray.position.y > box.min.y) && (ray.position.y < box.max.y) && @@ -6517,7 +6517,7 @@ static ModelAnimation *LoadModelAnimationsGLTF(const char *fileName, int *animCo }; } - Transform* root = &animations[i].framePoses[j][0]; + Transform *root = &animations[i].framePoses[j][0]; root->rotation = QuaternionMultiply(worldTransform.rotation, root->rotation); root->scale = Vector3Multiply(root->scale, worldTransform.scale); root->translation = Vector3Multiply(root->translation, worldTransform.scale); diff --git a/src/rshapes.c b/src/rshapes.c index 3f686f21a..7487e6296 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -59,9 +59,9 @@ //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -// Error rate to calculate how many segments we need to draw a smooth circle, -// taken from https://stackoverflow.com/a/2244088 #ifndef SMOOTH_CIRCLE_ERROR_RATE + // Define error rate to calculate how many segments are needed to draw a smooth circle + // REF: https://stackoverflow.com/a/2244088 #define SMOOTH_CIRCLE_ERROR_RATE 0.5f // Circle error rate #endif #ifndef SPLINE_SEGMENT_DIVISIONS @@ -318,7 +318,7 @@ void DrawCircle(int centerX, int centerY, float radius, Color color) } // Draw a color-filled circle (Vector version) -// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues +// NOTE: On OpenGL 3.3 and ES2 using QUADS to avoid drawing order issues void DrawCircleV(Vector2 center, float radius, Color color) { DrawCircleSector(center, radius, 0, 360, 36, color); @@ -379,7 +379,7 @@ void DrawCircleSector(Vector2 center, float radius, float startAngle, float endA angle += (stepLength*2.0f); } - // NOTE: In case number of segments is odd, we add one last piece to the cake + // NOTE: In case number of segments is odd, adding one last piece to the cake if ((((unsigned int)segments)%2) == 1) { rlColor4ub(color.r, color.g, color.b, color.a); @@ -722,7 +722,7 @@ void DrawRectangle(int posX, int posY, int width, int height, Color color) } // Draw a color-filled rectangle (Vector version) -// NOTE: On OpenGL 3.3 and ES2 we use QUADS to avoid drawing order issues +// NOTE: On OpenGL 3.3 and ES2 using QUADS to avoid drawing order issues void DrawRectangleV(Vector2 position, Vector2 size, Color color) { DrawRectanglePro((Rectangle){ position.x, position.y, size.x, size.y }, (Vector2){ 0.0f, 0.0f }, 0.0f, color); @@ -968,7 +968,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co /* Quick sketch to make sense of all of this, - there are 9 parts to draw, also mark the 12 points we'll use + there are 9 parts to draw, also mark the 12 points used P0____________________P1 /| |\ @@ -1024,7 +1024,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co angle += (stepLength*2); } - // NOTE: In case number of segments is odd, we add one last piece to the cake + // NOTE: In case number of segments is odd, adding one last piece to the cake if (segments%2) { rlColor4ub(color.r, color.g, color.b, color.a); @@ -1168,7 +1168,7 @@ void DrawRectangleRounded(Rectangle rec, float roundness, int segments, Color co // Draw rectangle with rounded edges void DrawRectangleRoundedLines(Rectangle rec, float roundness, int segments, Color color) { - // NOTE: For line thicknes <=1.0f we use RL_LINES, otherwise wee use RL_QUADS/RL_TRIANGLES + // NOTE: For line thicknes <=1.0f using RL_LINES, otherwise using RL_QUADS/RL_TRIANGLES DrawRectangleRoundedLinesEx(rec, roundness, segments, 1.0f, color); } @@ -1204,7 +1204,7 @@ void DrawRectangleRoundedLinesEx(Rectangle rec, float roundness, int segments, f /* Quick sketch to make sense of all of this, - marks the 16 + 4(corner centers P16-19) points we'll use + marks the 16 + 4(corner centers P16-19) points used P0 ================== P1 // P8 P9 \\ @@ -1946,7 +1946,7 @@ void DrawSplineBezierCubic(const Vector2 *points, int pointCount, float thick, C // Draw spline segment: Linear, 2 points void DrawSplineSegmentLinear(Vector2 p1, Vector2 p2, float thick, Color color) { - // NOTE: For the linear spline we don't use subdivisions, just a single quad + // NOTE: For the linear spline no subdivisions are used, just a single quad Vector2 delta = { p2.x - p1.x, p2.y - p1.y }; float length = sqrtf(delta.x*delta.x + delta.y*delta.y); diff --git a/src/rtext.c b/src/rtext.c index 45aa19b13..2c871cc49 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -1727,14 +1727,15 @@ char *GetTextBetween(const char *text, const char *begin, const char *end) // Replace text string // REQUIRES: strstr(), strncpy() -// TODO: If (replacement == "") remove "search" text // WARNING: Allocated memory must be manually freed char *TextReplace(const char *text, const char *search, const char *replacement) { char *result = NULL; if ((text != NULL) && (search != NULL)) - { + { + if (replacement == NULL) replacement = ""; + char *insertPoint = NULL; // Next insert point char *temp = NULL; // Temp pointer int textLen = 0; // Text string length @@ -1767,16 +1768,15 @@ char *TextReplace(const char *text, const char *search, const char *replacement) { insertPoint = (char *)strstr(text, search); lastReplacePos = (int)(insertPoint - text); - - // TODO: Review logic to avoid strcpy() - // OK - Those lines work - temp = strncpy(temp, text, lastReplacePos) + lastReplacePos; - temp = strcpy(temp, replacement) + replaceLen; - // WRONG - But not those ones - //temp = strncpy(temp, text, tempLen - 1) + lastReplacePos; - //tempLen -= lastReplacePos; - //temp = strncpy(temp, replacement, tempLen - 1) + replaceLen; - //tempLen -= replaceLen; + + memcpy(temp, text, lastReplacePos); + temp += lastReplacePos; + + if (replaceLen > 0) + { + memcpy(temp, replacement, replaceLen); + temp += replaceLen; + } text += lastReplacePos + searchLen; // Move to next "end of replace" } diff --git a/src/rtextures.c b/src/rtextures.c index a20b5e516..1aced0533 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -3625,7 +3625,7 @@ void ImageDrawLineEx(Image *dst, Vector2 start, Vector2 end, int thick, Color co } // Draw circle within an image -void ImageDrawCircle(Image* dst, int centerX, int centerY, int radius, Color color) +void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color) { int x = 0; int y = radius; @@ -3649,7 +3649,7 @@ void ImageDrawCircle(Image* dst, int centerX, int centerY, int radius, Color col } // Draw circle within an image (Vector version) -void ImageDrawCircleV(Image* dst, Vector2 center, int radius, Color color) +void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color) { ImageDrawCircle(dst, (int)center.x, (int)center.y, radius, color); } @@ -5602,4 +5602,4 @@ static Vector4 *LoadImageDataNormalized(Image image) return pixels; } -#endif // SUPPORT_MODULE_RTEXTURES +#endif // SUPPORT_MODULE_RTEXTURES \ No newline at end of file diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index ad9bcbed0..70001a5f3 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -1556,7 +1556,7 @@ int main(int argc, char *argv[]) "#include \n" "#include \n" "#include \n\n" - "static char logText[4096] = {0};\n" + "static char logText[4096] = { 0 };\n" "static int logTextOffset = 0;\n\n" "void CustomTraceLog(int msgType, const char *text, va_list args)\n{\n" " if (logTextOffset < 3800)\n {\n" diff --git a/tools/rlparser/output/raylib_api.json b/tools/rlparser/output/raylib_api.json index 185516563..d4c059c50 100644 --- a/tools/rlparser/output/raylib_api.json +++ b/tools/rlparser/output/raylib_api.json @@ -1324,11 +1324,6 @@ "name": "FilePathList", "description": "File path list", "fields": [ - { - "type": "unsigned int", - "name": "capacity", - "description": "Filepaths max entries" - }, { "type": "unsigned int", "name": "count", @@ -4734,6 +4729,36 @@ } ] }, + { + "name": "GetDirectoryFileCount", + "description": "Get the file count in a directory", + "returnType": "unsigned int", + "params": [ + { + "type": "const char *", + "name": "dirPath" + } + ] + }, + { + "name": "GetDirectoryFileCountEx", + "description": "Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result", + "returnType": "unsigned int", + "params": [ + { + "type": "const char *", + "name": "basePath" + }, + { + "type": "const char *", + "name": "filter" + }, + { + "type": "bool", + "name": "scanSubdirs" + } + ] + }, { "name": "CompressData", "description": "Compress data (DEFLATE algorithm), memory must be MemFree()", diff --git a/tools/rlparser/output/raylib_api.lua b/tools/rlparser/output/raylib_api.lua index f2836e1ff..2de69f69c 100644 --- a/tools/rlparser/output/raylib_api.lua +++ b/tools/rlparser/output/raylib_api.lua @@ -1324,11 +1324,6 @@ return { name = "FilePathList", description = "File path list", fields = { - { - type = "unsigned int", - name = "capacity", - description = "Filepaths max entries" - }, { type = "unsigned int", name = "count", @@ -4230,6 +4225,24 @@ return { {type = "FilePathList", name = "files"} } }, + { + name = "GetDirectoryFileCount", + description = "Get the file count in a directory", + returnType = "unsigned int", + params = { + {type = "const char *", name = "dirPath"} + } + }, + { + name = "GetDirectoryFileCountEx", + description = "Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result", + returnType = "unsigned int", + params = { + {type = "const char *", name = "basePath"}, + {type = "const char *", name = "filter"}, + {type = "bool", name = "scanSubdirs"} + } + }, { name = "CompressData", description = "Compress data (DEFLATE algorithm), memory must be MemFree()", diff --git a/tools/rlparser/output/raylib_api.txt b/tools/rlparser/output/raylib_api.txt index 0676b8138..53dbf8813 100644 --- a/tools/rlparser/output/raylib_api.txt +++ b/tools/rlparser/output/raylib_api.txt @@ -540,12 +540,11 @@ Struct 31: VrStereoConfig (8 fields) Field[6]: float[2] rightScreenCenter // VR right screen center Field[7]: float[2] scale // VR distortion scale Field[8]: float[2] scaleIn // VR distortion scale in -Struct 32: FilePathList (3 fields) +Struct 32: FilePathList (2 fields) Name: FilePathList Description: File path list - Field[1]: unsigned int capacity // Filepaths max entries - Field[2]: unsigned int count // Filepaths entries count - Field[3]: char ** paths // Filepaths entries + Field[1]: unsigned int count // Filepaths entries count + Field[2]: char ** paths // Filepaths entries Struct 33: AutomationEvent (3 fields) Name: AutomationEvent Description: Automation event @@ -993,7 +992,7 @@ Callback 006: AudioCallback() (2 input parameters) Param[1]: bufferData (type: void *) Param[2]: frames (type: unsigned int) -Functions found: 597 +Functions found: 599 Function 001: InitWindow() (3 input parameters) Name: InitWindow @@ -1806,199 +1805,211 @@ Function 151: UnloadDroppedFiles() (1 input parameters) Return type: void Description: Unload dropped filepaths Param[1]: files (type: FilePathList) -Function 152: CompressData() (3 input parameters) +Function 152: GetDirectoryFileCount() (1 input parameters) + Name: GetDirectoryFileCount + Return type: unsigned int + Description: Get the file count in a directory + Param[1]: dirPath (type: const char *) +Function 153: GetDirectoryFileCountEx() (3 input parameters) + Name: GetDirectoryFileCountEx + Return type: unsigned int + Description: Get the file count in a directory with extension filtering and recursive directory scan. Use 'DIR' in the filter string to include directories in the result + Param[1]: basePath (type: const char *) + Param[2]: filter (type: const char *) + Param[3]: scanSubdirs (type: bool) +Function 154: CompressData() (3 input parameters) Name: CompressData Return type: unsigned char * Description: Compress data (DEFLATE algorithm), memory must be MemFree() Param[1]: data (type: const unsigned char *) Param[2]: dataSize (type: int) Param[3]: compDataSize (type: int *) -Function 153: DecompressData() (3 input parameters) +Function 155: DecompressData() (3 input parameters) Name: DecompressData Return type: unsigned char * Description: Decompress data (DEFLATE algorithm), memory must be MemFree() Param[1]: compData (type: const unsigned char *) Param[2]: compDataSize (type: int) Param[3]: dataSize (type: int *) -Function 154: EncodeDataBase64() (3 input parameters) +Function 156: EncodeDataBase64() (3 input parameters) Name: EncodeDataBase64 Return type: char * Description: Encode data to Base64 string (includes NULL terminator), memory must be MemFree() Param[1]: data (type: const unsigned char *) Param[2]: dataSize (type: int) Param[3]: outputSize (type: int *) -Function 155: DecodeDataBase64() (2 input parameters) +Function 157: DecodeDataBase64() (2 input parameters) Name: DecodeDataBase64 Return type: unsigned char * Description: Decode Base64 string (expected NULL terminated), memory must be MemFree() Param[1]: text (type: const char *) Param[2]: outputSize (type: int *) -Function 156: ComputeCRC32() (2 input parameters) +Function 158: ComputeCRC32() (2 input parameters) Name: ComputeCRC32 Return type: unsigned int Description: Compute CRC32 hash code Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 157: ComputeMD5() (2 input parameters) +Function 159: ComputeMD5() (2 input parameters) Name: ComputeMD5 Return type: unsigned int * Description: Compute MD5 hash code, returns static int[4] (16 bytes) Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 158: ComputeSHA1() (2 input parameters) +Function 160: ComputeSHA1() (2 input parameters) Name: ComputeSHA1 Return type: unsigned int * Description: Compute SHA1 hash code, returns static int[5] (20 bytes) Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 159: ComputeSHA256() (2 input parameters) +Function 161: ComputeSHA256() (2 input parameters) Name: ComputeSHA256 Return type: unsigned int * Description: Compute SHA256 hash code, returns static int[8] (32 bytes) Param[1]: data (type: unsigned char *) Param[2]: dataSize (type: int) -Function 160: LoadAutomationEventList() (1 input parameters) +Function 162: LoadAutomationEventList() (1 input parameters) Name: LoadAutomationEventList Return type: AutomationEventList Description: Load automation events list from file, NULL for empty list, capacity = MAX_AUTOMATION_EVENTS Param[1]: fileName (type: const char *) -Function 161: UnloadAutomationEventList() (1 input parameters) +Function 163: UnloadAutomationEventList() (1 input parameters) Name: UnloadAutomationEventList Return type: void Description: Unload automation events list from file Param[1]: list (type: AutomationEventList) -Function 162: ExportAutomationEventList() (2 input parameters) +Function 164: ExportAutomationEventList() (2 input parameters) Name: ExportAutomationEventList Return type: bool Description: Export automation events list as text file Param[1]: list (type: AutomationEventList) Param[2]: fileName (type: const char *) -Function 163: SetAutomationEventList() (1 input parameters) +Function 165: SetAutomationEventList() (1 input parameters) Name: SetAutomationEventList Return type: void Description: Set automation event list to record to Param[1]: list (type: AutomationEventList *) -Function 164: SetAutomationEventBaseFrame() (1 input parameters) +Function 166: SetAutomationEventBaseFrame() (1 input parameters) Name: SetAutomationEventBaseFrame Return type: void Description: Set automation event internal base frame to start recording Param[1]: frame (type: int) -Function 165: StartAutomationEventRecording() (0 input parameters) +Function 167: StartAutomationEventRecording() (0 input parameters) Name: StartAutomationEventRecording Return type: void Description: Start recording automation events (AutomationEventList must be set) No input parameters -Function 166: StopAutomationEventRecording() (0 input parameters) +Function 168: StopAutomationEventRecording() (0 input parameters) Name: StopAutomationEventRecording Return type: void Description: Stop recording automation events No input parameters -Function 167: PlayAutomationEvent() (1 input parameters) +Function 169: PlayAutomationEvent() (1 input parameters) Name: PlayAutomationEvent Return type: void Description: Play a recorded automation event Param[1]: event (type: AutomationEvent) -Function 168: IsKeyPressed() (1 input parameters) +Function 170: IsKeyPressed() (1 input parameters) Name: IsKeyPressed Return type: bool Description: Check if a key has been pressed once Param[1]: key (type: int) -Function 169: IsKeyPressedRepeat() (1 input parameters) +Function 171: IsKeyPressedRepeat() (1 input parameters) Name: IsKeyPressedRepeat Return type: bool Description: Check if a key has been pressed again Param[1]: key (type: int) -Function 170: IsKeyDown() (1 input parameters) +Function 172: IsKeyDown() (1 input parameters) Name: IsKeyDown Return type: bool Description: Check if a key is being pressed Param[1]: key (type: int) -Function 171: IsKeyReleased() (1 input parameters) +Function 173: IsKeyReleased() (1 input parameters) Name: IsKeyReleased Return type: bool Description: Check if a key has been released once Param[1]: key (type: int) -Function 172: IsKeyUp() (1 input parameters) +Function 174: IsKeyUp() (1 input parameters) Name: IsKeyUp Return type: bool Description: Check if a key is NOT being pressed Param[1]: key (type: int) -Function 173: GetKeyPressed() (0 input parameters) +Function 175: GetKeyPressed() (0 input parameters) Name: GetKeyPressed Return type: int Description: Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty No input parameters -Function 174: GetCharPressed() (0 input parameters) +Function 176: GetCharPressed() (0 input parameters) Name: GetCharPressed Return type: int Description: Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty No input parameters -Function 175: GetKeyName() (1 input parameters) +Function 177: GetKeyName() (1 input parameters) Name: GetKeyName Return type: const char * Description: Get name of a QWERTY key on the current keyboard layout (eg returns string 'q' for KEY_A on an AZERTY keyboard) Param[1]: key (type: int) -Function 176: SetExitKey() (1 input parameters) +Function 178: SetExitKey() (1 input parameters) Name: SetExitKey Return type: void Description: Set a custom key to exit program (default is ESC) Param[1]: key (type: int) -Function 177: IsGamepadAvailable() (1 input parameters) +Function 179: IsGamepadAvailable() (1 input parameters) Name: IsGamepadAvailable Return type: bool Description: Check if a gamepad is available Param[1]: gamepad (type: int) -Function 178: GetGamepadName() (1 input parameters) +Function 180: GetGamepadName() (1 input parameters) Name: GetGamepadName Return type: const char * Description: Get gamepad internal name id Param[1]: gamepad (type: int) -Function 179: IsGamepadButtonPressed() (2 input parameters) +Function 181: IsGamepadButtonPressed() (2 input parameters) Name: IsGamepadButtonPressed Return type: bool Description: Check if a gamepad button has been pressed once Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 180: IsGamepadButtonDown() (2 input parameters) +Function 182: IsGamepadButtonDown() (2 input parameters) Name: IsGamepadButtonDown Return type: bool Description: Check if a gamepad button is being pressed Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 181: IsGamepadButtonReleased() (2 input parameters) +Function 183: IsGamepadButtonReleased() (2 input parameters) Name: IsGamepadButtonReleased Return type: bool Description: Check if a gamepad button has been released once Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 182: IsGamepadButtonUp() (2 input parameters) +Function 184: IsGamepadButtonUp() (2 input parameters) Name: IsGamepadButtonUp Return type: bool Description: Check if a gamepad button is NOT being pressed Param[1]: gamepad (type: int) Param[2]: button (type: int) -Function 183: GetGamepadButtonPressed() (0 input parameters) +Function 185: GetGamepadButtonPressed() (0 input parameters) Name: GetGamepadButtonPressed Return type: int Description: Get the last gamepad button pressed No input parameters -Function 184: GetGamepadAxisCount() (1 input parameters) +Function 186: GetGamepadAxisCount() (1 input parameters) Name: GetGamepadAxisCount Return type: int Description: Get axis count for a gamepad Param[1]: gamepad (type: int) -Function 185: GetGamepadAxisMovement() (2 input parameters) +Function 187: GetGamepadAxisMovement() (2 input parameters) Name: GetGamepadAxisMovement Return type: float Description: Get movement value for a gamepad axis Param[1]: gamepad (type: int) Param[2]: axis (type: int) -Function 186: SetGamepadMappings() (1 input parameters) +Function 188: SetGamepadMappings() (1 input parameters) Name: SetGamepadMappings Return type: int Description: Set internal gamepad mappings (SDL_GameControllerDB) Param[1]: mappings (type: const char *) -Function 187: SetGamepadVibration() (4 input parameters) +Function 189: SetGamepadVibration() (4 input parameters) Name: SetGamepadVibration Return type: void Description: Set gamepad vibration for both motors (duration in seconds) @@ -2006,151 +2017,151 @@ Function 187: SetGamepadVibration() (4 input parameters) Param[2]: leftMotor (type: float) Param[3]: rightMotor (type: float) Param[4]: duration (type: float) -Function 188: IsMouseButtonPressed() (1 input parameters) +Function 190: IsMouseButtonPressed() (1 input parameters) Name: IsMouseButtonPressed Return type: bool Description: Check if a mouse button has been pressed once Param[1]: button (type: int) -Function 189: IsMouseButtonDown() (1 input parameters) +Function 191: IsMouseButtonDown() (1 input parameters) Name: IsMouseButtonDown Return type: bool Description: Check if a mouse button is being pressed Param[1]: button (type: int) -Function 190: IsMouseButtonReleased() (1 input parameters) +Function 192: IsMouseButtonReleased() (1 input parameters) Name: IsMouseButtonReleased Return type: bool Description: Check if a mouse button has been released once Param[1]: button (type: int) -Function 191: IsMouseButtonUp() (1 input parameters) +Function 193: IsMouseButtonUp() (1 input parameters) Name: IsMouseButtonUp Return type: bool Description: Check if a mouse button is NOT being pressed Param[1]: button (type: int) -Function 192: GetMouseX() (0 input parameters) +Function 194: GetMouseX() (0 input parameters) Name: GetMouseX Return type: int Description: Get mouse position X No input parameters -Function 193: GetMouseY() (0 input parameters) +Function 195: GetMouseY() (0 input parameters) Name: GetMouseY Return type: int Description: Get mouse position Y No input parameters -Function 194: GetMousePosition() (0 input parameters) +Function 196: GetMousePosition() (0 input parameters) Name: GetMousePosition Return type: Vector2 Description: Get mouse position XY No input parameters -Function 195: GetMouseDelta() (0 input parameters) +Function 197: GetMouseDelta() (0 input parameters) Name: GetMouseDelta Return type: Vector2 Description: Get mouse delta between frames No input parameters -Function 196: SetMousePosition() (2 input parameters) +Function 198: SetMousePosition() (2 input parameters) Name: SetMousePosition Return type: void Description: Set mouse position XY Param[1]: x (type: int) Param[2]: y (type: int) -Function 197: SetMouseOffset() (2 input parameters) +Function 199: SetMouseOffset() (2 input parameters) Name: SetMouseOffset Return type: void Description: Set mouse offset Param[1]: offsetX (type: int) Param[2]: offsetY (type: int) -Function 198: SetMouseScale() (2 input parameters) +Function 200: SetMouseScale() (2 input parameters) Name: SetMouseScale Return type: void Description: Set mouse scaling Param[1]: scaleX (type: float) Param[2]: scaleY (type: float) -Function 199: GetMouseWheelMove() (0 input parameters) +Function 201: GetMouseWheelMove() (0 input parameters) Name: GetMouseWheelMove Return type: float Description: Get mouse wheel movement for X or Y, whichever is larger No input parameters -Function 200: GetMouseWheelMoveV() (0 input parameters) +Function 202: GetMouseWheelMoveV() (0 input parameters) Name: GetMouseWheelMoveV Return type: Vector2 Description: Get mouse wheel movement for both X and Y No input parameters -Function 201: SetMouseCursor() (1 input parameters) +Function 203: SetMouseCursor() (1 input parameters) Name: SetMouseCursor Return type: void Description: Set mouse cursor Param[1]: cursor (type: int) -Function 202: GetTouchX() (0 input parameters) +Function 204: GetTouchX() (0 input parameters) Name: GetTouchX Return type: int Description: Get touch position X for touch point 0 (relative to screen size) No input parameters -Function 203: GetTouchY() (0 input parameters) +Function 205: GetTouchY() (0 input parameters) Name: GetTouchY Return type: int Description: Get touch position Y for touch point 0 (relative to screen size) No input parameters -Function 204: GetTouchPosition() (1 input parameters) +Function 206: GetTouchPosition() (1 input parameters) Name: GetTouchPosition Return type: Vector2 Description: Get touch position XY for a touch point index (relative to screen size) Param[1]: index (type: int) -Function 205: GetTouchPointId() (1 input parameters) +Function 207: GetTouchPointId() (1 input parameters) Name: GetTouchPointId Return type: int Description: Get touch point identifier for given index Param[1]: index (type: int) -Function 206: GetTouchPointCount() (0 input parameters) +Function 208: GetTouchPointCount() (0 input parameters) Name: GetTouchPointCount Return type: int Description: Get number of touch points No input parameters -Function 207: SetGesturesEnabled() (1 input parameters) +Function 209: SetGesturesEnabled() (1 input parameters) Name: SetGesturesEnabled Return type: void Description: Enable a set of gestures using flags Param[1]: flags (type: unsigned int) -Function 208: IsGestureDetected() (1 input parameters) +Function 210: IsGestureDetected() (1 input parameters) Name: IsGestureDetected Return type: bool Description: Check if a gesture have been detected Param[1]: gesture (type: unsigned int) -Function 209: GetGestureDetected() (0 input parameters) +Function 211: GetGestureDetected() (0 input parameters) Name: GetGestureDetected Return type: int Description: Get latest detected gesture No input parameters -Function 210: GetGestureHoldDuration() (0 input parameters) +Function 212: GetGestureHoldDuration() (0 input parameters) Name: GetGestureHoldDuration Return type: float Description: Get gesture hold time in seconds No input parameters -Function 211: GetGestureDragVector() (0 input parameters) +Function 213: GetGestureDragVector() (0 input parameters) Name: GetGestureDragVector Return type: Vector2 Description: Get gesture drag vector No input parameters -Function 212: GetGestureDragAngle() (0 input parameters) +Function 214: GetGestureDragAngle() (0 input parameters) Name: GetGestureDragAngle Return type: float Description: Get gesture drag angle No input parameters -Function 213: GetGesturePinchVector() (0 input parameters) +Function 215: GetGesturePinchVector() (0 input parameters) Name: GetGesturePinchVector Return type: Vector2 Description: Get gesture pinch delta No input parameters -Function 214: GetGesturePinchAngle() (0 input parameters) +Function 216: GetGesturePinchAngle() (0 input parameters) Name: GetGesturePinchAngle Return type: float Description: Get gesture pinch angle No input parameters -Function 215: UpdateCamera() (2 input parameters) +Function 217: UpdateCamera() (2 input parameters) Name: UpdateCamera Return type: void Description: Update camera position for selected mode Param[1]: camera (type: Camera *) Param[2]: mode (type: int) -Function 216: UpdateCameraPro() (4 input parameters) +Function 218: UpdateCameraPro() (4 input parameters) Name: UpdateCameraPro Return type: void Description: Update camera movement/rotation @@ -2158,36 +2169,36 @@ Function 216: UpdateCameraPro() (4 input parameters) Param[2]: movement (type: Vector3) Param[3]: rotation (type: Vector3) Param[4]: zoom (type: float) -Function 217: SetShapesTexture() (2 input parameters) +Function 219: SetShapesTexture() (2 input parameters) Name: SetShapesTexture Return type: void Description: Set texture and rectangle to be used on shapes drawing Param[1]: texture (type: Texture2D) Param[2]: source (type: Rectangle) -Function 218: GetShapesTexture() (0 input parameters) +Function 220: GetShapesTexture() (0 input parameters) Name: GetShapesTexture Return type: Texture2D Description: Get texture that is used for shapes drawing No input parameters -Function 219: GetShapesTextureRectangle() (0 input parameters) +Function 221: GetShapesTextureRectangle() (0 input parameters) Name: GetShapesTextureRectangle Return type: Rectangle Description: Get texture source rectangle that is used for shapes drawing No input parameters -Function 220: DrawPixel() (3 input parameters) +Function 222: DrawPixel() (3 input parameters) Name: DrawPixel Return type: void Description: Draw a pixel using geometry [Can be slow, use with care] Param[1]: posX (type: int) Param[2]: posY (type: int) Param[3]: color (type: Color) -Function 221: DrawPixelV() (2 input parameters) +Function 223: DrawPixelV() (2 input parameters) Name: DrawPixelV Return type: void Description: Draw a pixel using geometry (Vector version) [Can be slow, use with care] Param[1]: position (type: Vector2) Param[2]: color (type: Color) -Function 222: DrawLine() (5 input parameters) +Function 224: DrawLine() (5 input parameters) Name: DrawLine Return type: void Description: Draw a line @@ -2196,14 +2207,14 @@ Function 222: DrawLine() (5 input parameters) Param[3]: endPosX (type: int) Param[4]: endPosY (type: int) Param[5]: color (type: Color) -Function 223: DrawLineV() (3 input parameters) +Function 225: DrawLineV() (3 input parameters) Name: DrawLineV Return type: void Description: Draw a line (using gl lines) Param[1]: startPos (type: Vector2) Param[2]: endPos (type: Vector2) Param[3]: color (type: Color) -Function 224: DrawLineEx() (4 input parameters) +Function 226: DrawLineEx() (4 input parameters) Name: DrawLineEx Return type: void Description: Draw a line (using triangles/quads) @@ -2211,14 +2222,14 @@ Function 224: DrawLineEx() (4 input parameters) Param[2]: endPos (type: Vector2) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 225: DrawLineStrip() (3 input parameters) +Function 227: DrawLineStrip() (3 input parameters) Name: DrawLineStrip Return type: void Description: Draw lines sequence (using gl lines) Param[1]: points (type: const Vector2 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 226: DrawLineBezier() (4 input parameters) +Function 228: DrawLineBezier() (4 input parameters) Name: DrawLineBezier Return type: void Description: Draw line segment cubic-bezier in-out interpolation @@ -2226,7 +2237,7 @@ Function 226: DrawLineBezier() (4 input parameters) Param[2]: endPos (type: Vector2) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 227: DrawLineDashed() (5 input parameters) +Function 229: DrawLineDashed() (5 input parameters) Name: DrawLineDashed Return type: void Description: Draw a dashed line @@ -2235,7 +2246,7 @@ Function 227: DrawLineDashed() (5 input parameters) Param[3]: dashSize (type: int) Param[4]: spaceSize (type: int) Param[5]: color (type: Color) -Function 228: DrawCircle() (4 input parameters) +Function 230: DrawCircle() (4 input parameters) Name: DrawCircle Return type: void Description: Draw a color-filled circle @@ -2243,7 +2254,7 @@ Function 228: DrawCircle() (4 input parameters) Param[2]: centerY (type: int) Param[3]: radius (type: float) Param[4]: color (type: Color) -Function 229: DrawCircleSector() (6 input parameters) +Function 231: DrawCircleSector() (6 input parameters) Name: DrawCircleSector Return type: void Description: Draw a piece of a circle @@ -2253,7 +2264,7 @@ Function 229: DrawCircleSector() (6 input parameters) Param[4]: endAngle (type: float) Param[5]: segments (type: int) Param[6]: color (type: Color) -Function 230: DrawCircleSectorLines() (6 input parameters) +Function 232: DrawCircleSectorLines() (6 input parameters) Name: DrawCircleSectorLines Return type: void Description: Draw circle sector outline @@ -2263,7 +2274,7 @@ Function 230: DrawCircleSectorLines() (6 input parameters) Param[4]: endAngle (type: float) Param[5]: segments (type: int) Param[6]: color (type: Color) -Function 231: DrawCircleGradient() (5 input parameters) +Function 233: DrawCircleGradient() (5 input parameters) Name: DrawCircleGradient Return type: void Description: Draw a gradient-filled circle @@ -2272,14 +2283,14 @@ Function 231: DrawCircleGradient() (5 input parameters) Param[3]: radius (type: float) Param[4]: inner (type: Color) Param[5]: outer (type: Color) -Function 232: DrawCircleV() (3 input parameters) +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 233: DrawCircleLines() (4 input parameters) +Function 235: DrawCircleLines() (4 input parameters) Name: DrawCircleLines Return type: void Description: Draw circle outline @@ -2287,14 +2298,14 @@ Function 233: DrawCircleLines() (4 input parameters) Param[2]: centerY (type: int) Param[3]: radius (type: float) Param[4]: color (type: Color) -Function 234: DrawCircleLinesV() (3 input parameters) +Function 236: DrawCircleLinesV() (3 input parameters) Name: DrawCircleLinesV Return type: void Description: Draw circle outline (Vector version) Param[1]: center (type: Vector2) Param[2]: radius (type: float) Param[3]: color (type: Color) -Function 235: DrawEllipse() (5 input parameters) +Function 237: DrawEllipse() (5 input parameters) Name: DrawEllipse Return type: void Description: Draw ellipse @@ -2303,7 +2314,7 @@ Function 235: DrawEllipse() (5 input parameters) Param[3]: radiusH (type: float) Param[4]: radiusV (type: float) Param[5]: color (type: Color) -Function 236: DrawEllipseV() (4 input parameters) +Function 238: DrawEllipseV() (4 input parameters) Name: DrawEllipseV Return type: void Description: Draw ellipse (Vector version) @@ -2311,7 +2322,7 @@ Function 236: DrawEllipseV() (4 input parameters) Param[2]: radiusH (type: float) Param[3]: radiusV (type: float) Param[4]: color (type: Color) -Function 237: DrawEllipseLines() (5 input parameters) +Function 239: DrawEllipseLines() (5 input parameters) Name: DrawEllipseLines Return type: void Description: Draw ellipse outline @@ -2320,7 +2331,7 @@ Function 237: DrawEllipseLines() (5 input parameters) Param[3]: radiusH (type: float) Param[4]: radiusV (type: float) Param[5]: color (type: Color) -Function 238: DrawEllipseLinesV() (4 input parameters) +Function 240: DrawEllipseLinesV() (4 input parameters) Name: DrawEllipseLinesV Return type: void Description: Draw ellipse outline (Vector version) @@ -2328,7 +2339,7 @@ Function 238: DrawEllipseLinesV() (4 input parameters) Param[2]: radiusH (type: float) Param[3]: radiusV (type: float) Param[4]: color (type: Color) -Function 239: DrawRing() (7 input parameters) +Function 241: DrawRing() (7 input parameters) Name: DrawRing Return type: void Description: Draw ring @@ -2339,7 +2350,7 @@ Function 239: DrawRing() (7 input parameters) Param[5]: endAngle (type: float) Param[6]: segments (type: int) Param[7]: color (type: Color) -Function 240: DrawRingLines() (7 input parameters) +Function 242: DrawRingLines() (7 input parameters) Name: DrawRingLines Return type: void Description: Draw ring outline @@ -2350,7 +2361,7 @@ Function 240: DrawRingLines() (7 input parameters) Param[5]: endAngle (type: float) Param[6]: segments (type: int) Param[7]: color (type: Color) -Function 241: DrawRectangle() (5 input parameters) +Function 243: DrawRectangle() (5 input parameters) Name: DrawRectangle Return type: void Description: Draw a color-filled rectangle @@ -2359,20 +2370,20 @@ Function 241: DrawRectangle() (5 input parameters) Param[3]: width (type: int) Param[4]: height (type: int) Param[5]: color (type: Color) -Function 242: DrawRectangleV() (3 input parameters) +Function 244: DrawRectangleV() (3 input parameters) Name: DrawRectangleV Return type: void Description: Draw a color-filled rectangle (Vector version) Param[1]: position (type: Vector2) Param[2]: size (type: Vector2) Param[3]: color (type: Color) -Function 243: DrawRectangleRec() (2 input parameters) +Function 245: DrawRectangleRec() (2 input parameters) Name: DrawRectangleRec Return type: void Description: Draw a color-filled rectangle Param[1]: rec (type: Rectangle) Param[2]: color (type: Color) -Function 244: DrawRectanglePro() (4 input parameters) +Function 246: DrawRectanglePro() (4 input parameters) Name: DrawRectanglePro Return type: void Description: Draw a color-filled rectangle with pro parameters @@ -2380,7 +2391,7 @@ Function 244: DrawRectanglePro() (4 input parameters) Param[2]: origin (type: Vector2) Param[3]: rotation (type: float) Param[4]: color (type: Color) -Function 245: DrawRectangleGradientV() (6 input parameters) +Function 247: DrawRectangleGradientV() (6 input parameters) Name: DrawRectangleGradientV Return type: void Description: Draw a vertical-gradient-filled rectangle @@ -2390,7 +2401,7 @@ Function 245: DrawRectangleGradientV() (6 input parameters) Param[4]: height (type: int) Param[5]: top (type: Color) Param[6]: bottom (type: Color) -Function 246: DrawRectangleGradientH() (6 input parameters) +Function 248: DrawRectangleGradientH() (6 input parameters) Name: DrawRectangleGradientH Return type: void Description: Draw a horizontal-gradient-filled rectangle @@ -2400,7 +2411,7 @@ Function 246: DrawRectangleGradientH() (6 input parameters) Param[4]: height (type: int) Param[5]: left (type: Color) Param[6]: right (type: Color) -Function 247: DrawRectangleGradientEx() (5 input parameters) +Function 249: DrawRectangleGradientEx() (5 input parameters) Name: DrawRectangleGradientEx Return type: void Description: Draw a gradient-filled rectangle with custom vertex colors @@ -2409,7 +2420,7 @@ Function 247: DrawRectangleGradientEx() (5 input parameters) Param[3]: bottomLeft (type: Color) Param[4]: bottomRight (type: Color) Param[5]: topRight (type: Color) -Function 248: DrawRectangleLines() (5 input parameters) +Function 250: DrawRectangleLines() (5 input parameters) Name: DrawRectangleLines Return type: void Description: Draw rectangle outline @@ -2418,14 +2429,14 @@ Function 248: DrawRectangleLines() (5 input parameters) Param[3]: width (type: int) Param[4]: height (type: int) Param[5]: color (type: Color) -Function 249: DrawRectangleLinesEx() (3 input parameters) +Function 251: DrawRectangleLinesEx() (3 input parameters) Name: DrawRectangleLinesEx Return type: void Description: Draw rectangle outline with extended parameters Param[1]: rec (type: Rectangle) Param[2]: lineThick (type: float) Param[3]: color (type: Color) -Function 250: DrawRectangleRounded() (4 input parameters) +Function 252: DrawRectangleRounded() (4 input parameters) Name: DrawRectangleRounded Return type: void Description: Draw rectangle with rounded edges @@ -2433,7 +2444,7 @@ Function 250: DrawRectangleRounded() (4 input parameters) Param[2]: roundness (type: float) Param[3]: segments (type: int) Param[4]: color (type: Color) -Function 251: DrawRectangleRoundedLines() (4 input parameters) +Function 253: DrawRectangleRoundedLines() (4 input parameters) Name: DrawRectangleRoundedLines Return type: void Description: Draw rectangle lines with rounded edges @@ -2441,7 +2452,7 @@ Function 251: DrawRectangleRoundedLines() (4 input parameters) Param[2]: roundness (type: float) Param[3]: segments (type: int) Param[4]: color (type: Color) -Function 252: DrawRectangleRoundedLinesEx() (5 input parameters) +Function 254: DrawRectangleRoundedLinesEx() (5 input parameters) Name: DrawRectangleRoundedLinesEx Return type: void Description: Draw rectangle with rounded edges outline @@ -2450,7 +2461,7 @@ Function 252: DrawRectangleRoundedLinesEx() (5 input parameters) Param[3]: segments (type: int) Param[4]: lineThick (type: float) Param[5]: color (type: Color) -Function 253: DrawTriangle() (4 input parameters) +Function 255: DrawTriangle() (4 input parameters) Name: DrawTriangle Return type: void Description: Draw a color-filled triangle (vertex in counter-clockwise order!) @@ -2458,7 +2469,7 @@ Function 253: DrawTriangle() (4 input parameters) Param[2]: v2 (type: Vector2) Param[3]: v3 (type: Vector2) Param[4]: color (type: Color) -Function 254: DrawTriangleLines() (4 input parameters) +Function 256: DrawTriangleLines() (4 input parameters) Name: DrawTriangleLines Return type: void Description: Draw triangle outline (vertex in counter-clockwise order!) @@ -2466,21 +2477,21 @@ Function 254: DrawTriangleLines() (4 input parameters) Param[2]: v2 (type: Vector2) Param[3]: v3 (type: Vector2) Param[4]: color (type: Color) -Function 255: DrawTriangleFan() (3 input parameters) +Function 257: DrawTriangleFan() (3 input parameters) Name: DrawTriangleFan Return type: void Description: Draw a triangle fan defined by points (first vertex is the center) Param[1]: points (type: const Vector2 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 256: DrawTriangleStrip() (3 input parameters) +Function 258: DrawTriangleStrip() (3 input parameters) Name: DrawTriangleStrip Return type: void Description: Draw a triangle strip defined by points Param[1]: points (type: const Vector2 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 257: DrawPoly() (5 input parameters) +Function 259: DrawPoly() (5 input parameters) Name: DrawPoly Return type: void Description: Draw a regular polygon (Vector version) @@ -2489,7 +2500,7 @@ Function 257: DrawPoly() (5 input parameters) Param[3]: radius (type: float) Param[4]: rotation (type: float) Param[5]: color (type: Color) -Function 258: DrawPolyLines() (5 input parameters) +Function 260: DrawPolyLines() (5 input parameters) Name: DrawPolyLines Return type: void Description: Draw a polygon outline of n sides @@ -2498,7 +2509,7 @@ Function 258: DrawPolyLines() (5 input parameters) Param[3]: radius (type: float) Param[4]: rotation (type: float) Param[5]: color (type: Color) -Function 259: DrawPolyLinesEx() (6 input parameters) +Function 261: DrawPolyLinesEx() (6 input parameters) Name: DrawPolyLinesEx Return type: void Description: Draw a polygon outline of n sides with extended parameters @@ -2508,7 +2519,7 @@ Function 259: DrawPolyLinesEx() (6 input parameters) Param[4]: rotation (type: float) Param[5]: lineThick (type: float) Param[6]: color (type: Color) -Function 260: DrawSplineLinear() (4 input parameters) +Function 262: DrawSplineLinear() (4 input parameters) Name: DrawSplineLinear Return type: void Description: Draw spline: Linear, minimum 2 points @@ -2516,7 +2527,7 @@ Function 260: DrawSplineLinear() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 261: DrawSplineBasis() (4 input parameters) +Function 263: DrawSplineBasis() (4 input parameters) Name: DrawSplineBasis Return type: void Description: Draw spline: B-Spline, minimum 4 points @@ -2524,7 +2535,7 @@ Function 261: DrawSplineBasis() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 262: DrawSplineCatmullRom() (4 input parameters) +Function 264: DrawSplineCatmullRom() (4 input parameters) Name: DrawSplineCatmullRom Return type: void Description: Draw spline: Catmull-Rom, minimum 4 points @@ -2532,7 +2543,7 @@ Function 262: DrawSplineCatmullRom() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 263: DrawSplineBezierQuadratic() (4 input parameters) +Function 265: DrawSplineBezierQuadratic() (4 input parameters) Name: DrawSplineBezierQuadratic Return type: void Description: Draw spline: Quadratic Bezier, minimum 3 points (1 control point): [p1, c2, p3, c4...] @@ -2540,7 +2551,7 @@ Function 263: DrawSplineBezierQuadratic() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 264: DrawSplineBezierCubic() (4 input parameters) +Function 266: DrawSplineBezierCubic() (4 input parameters) Name: DrawSplineBezierCubic Return type: void Description: Draw spline: Cubic Bezier, minimum 4 points (2 control points): [p1, c2, c3, p4, c5, c6...] @@ -2548,7 +2559,7 @@ Function 264: DrawSplineBezierCubic() (4 input parameters) Param[2]: pointCount (type: int) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 265: DrawSplineSegmentLinear() (4 input parameters) +Function 267: DrawSplineSegmentLinear() (4 input parameters) Name: DrawSplineSegmentLinear Return type: void Description: Draw spline segment: Linear, 2 points @@ -2556,7 +2567,7 @@ Function 265: DrawSplineSegmentLinear() (4 input parameters) Param[2]: p2 (type: Vector2) Param[3]: thick (type: float) Param[4]: color (type: Color) -Function 266: DrawSplineSegmentBasis() (6 input parameters) +Function 268: DrawSplineSegmentBasis() (6 input parameters) Name: DrawSplineSegmentBasis Return type: void Description: Draw spline segment: B-Spline, 4 points @@ -2566,7 +2577,7 @@ Function 266: DrawSplineSegmentBasis() (6 input parameters) Param[4]: p4 (type: Vector2) Param[5]: thick (type: float) Param[6]: color (type: Color) -Function 267: DrawSplineSegmentCatmullRom() (6 input parameters) +Function 269: DrawSplineSegmentCatmullRom() (6 input parameters) Name: DrawSplineSegmentCatmullRom Return type: void Description: Draw spline segment: Catmull-Rom, 4 points @@ -2576,7 +2587,7 @@ Function 267: DrawSplineSegmentCatmullRom() (6 input parameters) Param[4]: p4 (type: Vector2) Param[5]: thick (type: float) Param[6]: color (type: Color) -Function 268: DrawSplineSegmentBezierQuadratic() (5 input parameters) +Function 270: DrawSplineSegmentBezierQuadratic() (5 input parameters) Name: DrawSplineSegmentBezierQuadratic Return type: void Description: Draw spline segment: Quadratic Bezier, 2 points, 1 control point @@ -2585,7 +2596,7 @@ Function 268: DrawSplineSegmentBezierQuadratic() (5 input parameters) Param[3]: p3 (type: Vector2) Param[4]: thick (type: float) Param[5]: color (type: Color) -Function 269: DrawSplineSegmentBezierCubic() (6 input parameters) +Function 271: DrawSplineSegmentBezierCubic() (6 input parameters) Name: DrawSplineSegmentBezierCubic Return type: void Description: Draw spline segment: Cubic Bezier, 2 points, 2 control points @@ -2595,14 +2606,14 @@ Function 269: DrawSplineSegmentBezierCubic() (6 input parameters) Param[4]: p4 (type: Vector2) Param[5]: thick (type: float) Param[6]: color (type: Color) -Function 270: GetSplinePointLinear() (3 input parameters) +Function 272: GetSplinePointLinear() (3 input parameters) Name: GetSplinePointLinear Return type: Vector2 Description: Get (evaluate) spline point: Linear Param[1]: startPos (type: Vector2) Param[2]: endPos (type: Vector2) Param[3]: t (type: float) -Function 271: GetSplinePointBasis() (5 input parameters) +Function 273: GetSplinePointBasis() (5 input parameters) Name: GetSplinePointBasis Return type: Vector2 Description: Get (evaluate) spline point: B-Spline @@ -2611,7 +2622,7 @@ Function 271: GetSplinePointBasis() (5 input parameters) Param[3]: p3 (type: Vector2) Param[4]: p4 (type: Vector2) Param[5]: t (type: float) -Function 272: GetSplinePointCatmullRom() (5 input parameters) +Function 274: GetSplinePointCatmullRom() (5 input parameters) Name: GetSplinePointCatmullRom Return type: Vector2 Description: Get (evaluate) spline point: Catmull-Rom @@ -2620,7 +2631,7 @@ Function 272: GetSplinePointCatmullRom() (5 input parameters) Param[3]: p3 (type: Vector2) Param[4]: p4 (type: Vector2) Param[5]: t (type: float) -Function 273: GetSplinePointBezierQuad() (4 input parameters) +Function 275: GetSplinePointBezierQuad() (4 input parameters) Name: GetSplinePointBezierQuad Return type: Vector2 Description: Get (evaluate) spline point: Quadratic Bezier @@ -2628,7 +2639,7 @@ Function 273: GetSplinePointBezierQuad() (4 input parameters) Param[2]: c2 (type: Vector2) Param[3]: p3 (type: Vector2) Param[4]: t (type: float) -Function 274: GetSplinePointBezierCubic() (5 input parameters) +Function 276: GetSplinePointBezierCubic() (5 input parameters) Name: GetSplinePointBezierCubic Return type: Vector2 Description: Get (evaluate) spline point: Cubic Bezier @@ -2637,13 +2648,13 @@ Function 274: GetSplinePointBezierCubic() (5 input parameters) Param[3]: c3 (type: Vector2) Param[4]: p4 (type: Vector2) Param[5]: t (type: float) -Function 275: CheckCollisionRecs() (2 input parameters) +Function 277: CheckCollisionRecs() (2 input parameters) Name: CheckCollisionRecs Return type: bool Description: Check collision between two rectangles Param[1]: rec1 (type: Rectangle) Param[2]: rec2 (type: Rectangle) -Function 276: CheckCollisionCircles() (4 input parameters) +Function 278: CheckCollisionCircles() (4 input parameters) Name: CheckCollisionCircles Return type: bool Description: Check collision between two circles @@ -2651,14 +2662,14 @@ Function 276: CheckCollisionCircles() (4 input parameters) Param[2]: radius1 (type: float) Param[3]: center2 (type: Vector2) Param[4]: radius2 (type: float) -Function 277: CheckCollisionCircleRec() (3 input parameters) +Function 279: CheckCollisionCircleRec() (3 input parameters) Name: CheckCollisionCircleRec Return type: bool Description: Check collision between circle and rectangle Param[1]: center (type: Vector2) Param[2]: radius (type: float) Param[3]: rec (type: Rectangle) -Function 278: CheckCollisionCircleLine() (4 input parameters) +Function 280: CheckCollisionCircleLine() (4 input parameters) Name: CheckCollisionCircleLine Return type: bool Description: Check if circle collides with a line created betweeen two points [p1] and [p2] @@ -2666,20 +2677,20 @@ Function 278: CheckCollisionCircleLine() (4 input parameters) Param[2]: radius (type: float) Param[3]: p1 (type: Vector2) Param[4]: p2 (type: Vector2) -Function 279: CheckCollisionPointRec() (2 input parameters) +Function 281: CheckCollisionPointRec() (2 input parameters) Name: CheckCollisionPointRec Return type: bool Description: Check if point is inside rectangle Param[1]: point (type: Vector2) Param[2]: rec (type: Rectangle) -Function 280: CheckCollisionPointCircle() (3 input parameters) +Function 282: CheckCollisionPointCircle() (3 input parameters) Name: CheckCollisionPointCircle Return type: bool Description: Check if point is inside circle Param[1]: point (type: Vector2) Param[2]: center (type: Vector2) Param[3]: radius (type: float) -Function 281: CheckCollisionPointTriangle() (4 input parameters) +Function 283: CheckCollisionPointTriangle() (4 input parameters) Name: CheckCollisionPointTriangle Return type: bool Description: Check if point is inside a triangle @@ -2687,7 +2698,7 @@ Function 281: CheckCollisionPointTriangle() (4 input parameters) Param[2]: p1 (type: Vector2) Param[3]: p2 (type: Vector2) Param[4]: p3 (type: Vector2) -Function 282: CheckCollisionPointLine() (4 input parameters) +Function 284: CheckCollisionPointLine() (4 input parameters) Name: CheckCollisionPointLine Return type: bool Description: Check if point belongs to line created between two points [p1] and [p2] with defined margin in pixels [threshold] @@ -2695,14 +2706,14 @@ Function 282: CheckCollisionPointLine() (4 input parameters) Param[2]: p1 (type: Vector2) Param[3]: p2 (type: Vector2) Param[4]: threshold (type: int) -Function 283: CheckCollisionPointPoly() (3 input parameters) +Function 285: CheckCollisionPointPoly() (3 input parameters) Name: CheckCollisionPointPoly Return type: bool Description: Check if point is within a polygon described by array of vertices Param[1]: point (type: Vector2) Param[2]: points (type: const Vector2 *) Param[3]: pointCount (type: int) -Function 284: CheckCollisionLines() (5 input parameters) +Function 286: CheckCollisionLines() (5 input parameters) Name: CheckCollisionLines Return type: bool Description: Check the collision between two lines defined by two points each, returns collision point by reference @@ -2711,18 +2722,18 @@ Function 284: CheckCollisionLines() (5 input parameters) Param[3]: startPos2 (type: Vector2) Param[4]: endPos2 (type: Vector2) Param[5]: collisionPoint (type: Vector2 *) -Function 285: GetCollisionRec() (2 input parameters) +Function 287: GetCollisionRec() (2 input parameters) Name: GetCollisionRec Return type: Rectangle Description: Get collision rectangle for two rectangles collision Param[1]: rec1 (type: Rectangle) Param[2]: rec2 (type: Rectangle) -Function 286: LoadImage() (1 input parameters) +Function 288: LoadImage() (1 input parameters) Name: LoadImage Return type: Image Description: Load image from file into CPU memory (RAM) Param[1]: fileName (type: const char *) -Function 287: LoadImageRaw() (5 input parameters) +Function 289: LoadImageRaw() (5 input parameters) Name: LoadImageRaw Return type: Image Description: Load image from RAW file data @@ -2731,13 +2742,13 @@ Function 287: LoadImageRaw() (5 input parameters) Param[3]: height (type: int) Param[4]: format (type: int) Param[5]: headerSize (type: int) -Function 288: LoadImageAnim() (2 input parameters) +Function 290: LoadImageAnim() (2 input parameters) Name: LoadImageAnim Return type: Image Description: Load image sequence from file (frames appended to image.data) Param[1]: fileName (type: const char *) Param[2]: frames (type: int *) -Function 289: LoadImageAnimFromMemory() (4 input parameters) +Function 291: LoadImageAnimFromMemory() (4 input parameters) Name: LoadImageAnimFromMemory Return type: Image Description: Load image sequence from memory buffer @@ -2745,60 +2756,60 @@ Function 289: LoadImageAnimFromMemory() (4 input parameters) Param[2]: fileData (type: const unsigned char *) Param[3]: dataSize (type: int) Param[4]: frames (type: int *) -Function 290: LoadImageFromMemory() (3 input parameters) +Function 292: LoadImageFromMemory() (3 input parameters) Name: LoadImageFromMemory Return type: Image Description: Load image from memory buffer, fileType refers to extension: i.e. '.png' Param[1]: fileType (type: const char *) Param[2]: fileData (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 291: LoadImageFromTexture() (1 input parameters) +Function 293: LoadImageFromTexture() (1 input parameters) Name: LoadImageFromTexture Return type: Image Description: Load image from GPU texture data Param[1]: texture (type: Texture2D) -Function 292: LoadImageFromScreen() (0 input parameters) +Function 294: LoadImageFromScreen() (0 input parameters) Name: LoadImageFromScreen Return type: Image Description: Load image from screen buffer and (screenshot) No input parameters -Function 293: IsImageValid() (1 input parameters) +Function 295: IsImageValid() (1 input parameters) Name: IsImageValid Return type: bool Description: Check if an image is valid (data and parameters) Param[1]: image (type: Image) -Function 294: UnloadImage() (1 input parameters) +Function 296: UnloadImage() (1 input parameters) Name: UnloadImage Return type: void Description: Unload image from CPU memory (RAM) Param[1]: image (type: Image) -Function 295: ExportImage() (2 input parameters) +Function 297: ExportImage() (2 input parameters) Name: ExportImage Return type: bool Description: Export image data to file, returns true on success Param[1]: image (type: Image) Param[2]: fileName (type: const char *) -Function 296: ExportImageToMemory() (3 input parameters) +Function 298: ExportImageToMemory() (3 input parameters) Name: ExportImageToMemory Return type: unsigned char * Description: Export image to memory buffer Param[1]: image (type: Image) Param[2]: fileType (type: const char *) Param[3]: fileSize (type: int *) -Function 297: ExportImageAsCode() (2 input parameters) +Function 299: ExportImageAsCode() (2 input parameters) Name: ExportImageAsCode Return type: bool Description: Export image as code file defining an array of bytes, returns true on success Param[1]: image (type: Image) Param[2]: fileName (type: const char *) -Function 298: GenImageColor() (3 input parameters) +Function 300: GenImageColor() (3 input parameters) Name: GenImageColor Return type: Image Description: Generate image: plain color Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: color (type: Color) -Function 299: GenImageGradientLinear() (5 input parameters) +Function 301: GenImageGradientLinear() (5 input parameters) Name: GenImageGradientLinear Return type: Image Description: Generate image: linear gradient, direction in degrees [0..360], 0=Vertical gradient @@ -2807,7 +2818,7 @@ Function 299: GenImageGradientLinear() (5 input parameters) Param[3]: direction (type: int) Param[4]: start (type: Color) Param[5]: end (type: Color) -Function 300: GenImageGradientRadial() (5 input parameters) +Function 302: GenImageGradientRadial() (5 input parameters) Name: GenImageGradientRadial Return type: Image Description: Generate image: radial gradient @@ -2816,7 +2827,7 @@ Function 300: GenImageGradientRadial() (5 input parameters) Param[3]: density (type: float) Param[4]: inner (type: Color) Param[5]: outer (type: Color) -Function 301: GenImageGradientSquare() (5 input parameters) +Function 303: GenImageGradientSquare() (5 input parameters) Name: GenImageGradientSquare Return type: Image Description: Generate image: square gradient @@ -2825,7 +2836,7 @@ Function 301: GenImageGradientSquare() (5 input parameters) Param[3]: density (type: float) Param[4]: inner (type: Color) Param[5]: outer (type: Color) -Function 302: GenImageChecked() (6 input parameters) +Function 304: GenImageChecked() (6 input parameters) Name: GenImageChecked Return type: Image Description: Generate image: checked @@ -2835,14 +2846,14 @@ Function 302: GenImageChecked() (6 input parameters) Param[4]: checksY (type: int) Param[5]: col1 (type: Color) Param[6]: col2 (type: Color) -Function 303: GenImageWhiteNoise() (3 input parameters) +Function 305: GenImageWhiteNoise() (3 input parameters) Name: GenImageWhiteNoise Return type: Image Description: Generate image: white noise Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: factor (type: float) -Function 304: GenImagePerlinNoise() (5 input parameters) +Function 306: GenImagePerlinNoise() (5 input parameters) Name: GenImagePerlinNoise Return type: Image Description: Generate image: perlin noise @@ -2851,45 +2862,45 @@ Function 304: GenImagePerlinNoise() (5 input parameters) Param[3]: offsetX (type: int) Param[4]: offsetY (type: int) Param[5]: scale (type: float) -Function 305: GenImageCellular() (3 input parameters) +Function 307: GenImageCellular() (3 input parameters) Name: GenImageCellular Return type: Image Description: Generate image: cellular algorithm, bigger tileSize means bigger cells Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: tileSize (type: int) -Function 306: GenImageText() (3 input parameters) +Function 308: GenImageText() (3 input parameters) Name: GenImageText Return type: Image Description: Generate image: grayscale image from text data Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: text (type: const char *) -Function 307: ImageCopy() (1 input parameters) +Function 309: ImageCopy() (1 input parameters) Name: ImageCopy Return type: Image Description: Create an image duplicate (useful for transformations) Param[1]: image (type: Image) -Function 308: ImageFromImage() (2 input parameters) +Function 310: ImageFromImage() (2 input parameters) Name: ImageFromImage Return type: Image Description: Create an image from another image piece Param[1]: image (type: Image) Param[2]: rec (type: Rectangle) -Function 309: ImageFromChannel() (2 input parameters) +Function 311: ImageFromChannel() (2 input parameters) Name: ImageFromChannel Return type: Image Description: Create an image from a selected channel of another image (GRAYSCALE) Param[1]: image (type: Image) Param[2]: selectedChannel (type: int) -Function 310: ImageText() (3 input parameters) +Function 312: ImageText() (3 input parameters) Name: ImageText Return type: Image Description: Create an image from text (default font) Param[1]: text (type: const char *) Param[2]: fontSize (type: int) Param[3]: color (type: Color) -Function 311: ImageTextEx() (5 input parameters) +Function 313: ImageTextEx() (5 input parameters) Name: ImageTextEx Return type: Image Description: Create an image from text (custom sprite font) @@ -2898,76 +2909,76 @@ Function 311: ImageTextEx() (5 input parameters) Param[3]: fontSize (type: float) Param[4]: spacing (type: float) Param[5]: tint (type: Color) -Function 312: ImageFormat() (2 input parameters) +Function 314: ImageFormat() (2 input parameters) Name: ImageFormat Return type: void Description: Convert image data to desired format Param[1]: image (type: Image *) Param[2]: newFormat (type: int) -Function 313: ImageToPOT() (2 input parameters) +Function 315: ImageToPOT() (2 input parameters) Name: ImageToPOT Return type: void Description: Convert image to POT (power-of-two) Param[1]: image (type: Image *) Param[2]: fill (type: Color) -Function 314: ImageCrop() (2 input parameters) +Function 316: ImageCrop() (2 input parameters) Name: ImageCrop Return type: void Description: Crop an image to a defined rectangle Param[1]: image (type: Image *) Param[2]: crop (type: Rectangle) -Function 315: ImageAlphaCrop() (2 input parameters) +Function 317: ImageAlphaCrop() (2 input parameters) Name: ImageAlphaCrop Return type: void Description: Crop image depending on alpha value Param[1]: image (type: Image *) Param[2]: threshold (type: float) -Function 316: ImageAlphaClear() (3 input parameters) +Function 318: ImageAlphaClear() (3 input parameters) Name: ImageAlphaClear Return type: void Description: Clear alpha channel to desired color Param[1]: image (type: Image *) Param[2]: color (type: Color) Param[3]: threshold (type: float) -Function 317: ImageAlphaMask() (2 input parameters) +Function 319: ImageAlphaMask() (2 input parameters) Name: ImageAlphaMask Return type: void Description: Apply alpha mask to image Param[1]: image (type: Image *) Param[2]: alphaMask (type: Image) -Function 318: ImageAlphaPremultiply() (1 input parameters) +Function 320: ImageAlphaPremultiply() (1 input parameters) Name: ImageAlphaPremultiply Return type: void Description: Premultiply alpha channel Param[1]: image (type: Image *) -Function 319: ImageBlurGaussian() (2 input parameters) +Function 321: ImageBlurGaussian() (2 input parameters) Name: ImageBlurGaussian Return type: void Description: Apply Gaussian blur using a box blur approximation Param[1]: image (type: Image *) Param[2]: blurSize (type: int) -Function 320: ImageKernelConvolution() (3 input parameters) +Function 322: ImageKernelConvolution() (3 input parameters) Name: ImageKernelConvolution Return type: void Description: Apply custom square convolution kernel to image Param[1]: image (type: Image *) Param[2]: kernel (type: const float *) Param[3]: kernelSize (type: int) -Function 321: ImageResize() (3 input parameters) +Function 323: ImageResize() (3 input parameters) Name: ImageResize Return type: void Description: Resize image (Bicubic scaling algorithm) Param[1]: image (type: Image *) Param[2]: newWidth (type: int) Param[3]: newHeight (type: int) -Function 322: ImageResizeNN() (3 input parameters) +Function 324: ImageResizeNN() (3 input parameters) Name: ImageResizeNN Return type: void Description: Resize image (Nearest-Neighbor scaling algorithm) Param[1]: image (type: Image *) Param[2]: newWidth (type: int) Param[3]: newHeight (type: int) -Function 323: ImageResizeCanvas() (6 input parameters) +Function 325: ImageResizeCanvas() (6 input parameters) Name: ImageResizeCanvas Return type: void Description: Resize canvas and fill with color @@ -2977,12 +2988,12 @@ Function 323: ImageResizeCanvas() (6 input parameters) Param[4]: offsetX (type: int) Param[5]: offsetY (type: int) Param[6]: fill (type: Color) -Function 324: ImageMipmaps() (1 input parameters) +Function 326: ImageMipmaps() (1 input parameters) Name: ImageMipmaps Return type: void Description: Compute all mipmap levels for a provided image Param[1]: image (type: Image *) -Function 325: ImageDither() (5 input parameters) +Function 327: ImageDither() (5 input parameters) Name: ImageDither Return type: void Description: Dither image data to 16bpp or lower (Floyd-Steinberg dithering) @@ -2991,109 +3002,109 @@ Function 325: ImageDither() (5 input parameters) Param[3]: gBpp (type: int) Param[4]: bBpp (type: int) Param[5]: aBpp (type: int) -Function 326: ImageFlipVertical() (1 input parameters) +Function 328: ImageFlipVertical() (1 input parameters) Name: ImageFlipVertical Return type: void Description: Flip image vertically Param[1]: image (type: Image *) -Function 327: ImageFlipHorizontal() (1 input parameters) +Function 329: ImageFlipHorizontal() (1 input parameters) Name: ImageFlipHorizontal Return type: void Description: Flip image horizontally Param[1]: image (type: Image *) -Function 328: ImageRotate() (2 input parameters) +Function 330: ImageRotate() (2 input parameters) Name: ImageRotate Return type: void Description: Rotate image by input angle in degrees (-359 to 359) Param[1]: image (type: Image *) Param[2]: degrees (type: int) -Function 329: ImageRotateCW() (1 input parameters) +Function 331: ImageRotateCW() (1 input parameters) Name: ImageRotateCW Return type: void Description: Rotate image clockwise 90deg Param[1]: image (type: Image *) -Function 330: ImageRotateCCW() (1 input parameters) +Function 332: ImageRotateCCW() (1 input parameters) Name: ImageRotateCCW Return type: void Description: Rotate image counter-clockwise 90deg Param[1]: image (type: Image *) -Function 331: ImageColorTint() (2 input parameters) +Function 333: ImageColorTint() (2 input parameters) Name: ImageColorTint Return type: void Description: Modify image color: tint Param[1]: image (type: Image *) Param[2]: color (type: Color) -Function 332: ImageColorInvert() (1 input parameters) +Function 334: ImageColorInvert() (1 input parameters) Name: ImageColorInvert Return type: void Description: Modify image color: invert Param[1]: image (type: Image *) -Function 333: ImageColorGrayscale() (1 input parameters) +Function 335: ImageColorGrayscale() (1 input parameters) Name: ImageColorGrayscale Return type: void Description: Modify image color: grayscale Param[1]: image (type: Image *) -Function 334: ImageColorContrast() (2 input parameters) +Function 336: ImageColorContrast() (2 input parameters) Name: ImageColorContrast Return type: void Description: Modify image color: contrast (-100 to 100) Param[1]: image (type: Image *) Param[2]: contrast (type: float) -Function 335: ImageColorBrightness() (2 input parameters) +Function 337: ImageColorBrightness() (2 input parameters) Name: ImageColorBrightness Return type: void Description: Modify image color: brightness (-255 to 255) Param[1]: image (type: Image *) Param[2]: brightness (type: int) -Function 336: ImageColorReplace() (3 input parameters) +Function 338: ImageColorReplace() (3 input parameters) Name: ImageColorReplace Return type: void Description: Modify image color: replace color Param[1]: image (type: Image *) Param[2]: color (type: Color) Param[3]: replace (type: Color) -Function 337: LoadImageColors() (1 input parameters) +Function 339: LoadImageColors() (1 input parameters) Name: LoadImageColors Return type: Color * Description: Load color data from image as a Color array (RGBA - 32bit) Param[1]: image (type: Image) -Function 338: LoadImagePalette() (3 input parameters) +Function 340: LoadImagePalette() (3 input parameters) Name: LoadImagePalette Return type: Color * Description: Load colors palette from image as a Color array (RGBA - 32bit) Param[1]: image (type: Image) Param[2]: maxPaletteSize (type: int) Param[3]: colorCount (type: int *) -Function 339: UnloadImageColors() (1 input parameters) +Function 341: UnloadImageColors() (1 input parameters) Name: UnloadImageColors Return type: void Description: Unload color data loaded with LoadImageColors() Param[1]: colors (type: Color *) -Function 340: UnloadImagePalette() (1 input parameters) +Function 342: UnloadImagePalette() (1 input parameters) Name: UnloadImagePalette Return type: void Description: Unload colors palette loaded with LoadImagePalette() Param[1]: colors (type: Color *) -Function 341: GetImageAlphaBorder() (2 input parameters) +Function 343: GetImageAlphaBorder() (2 input parameters) Name: GetImageAlphaBorder Return type: Rectangle Description: Get image alpha border rectangle Param[1]: image (type: Image) Param[2]: threshold (type: float) -Function 342: GetImageColor() (3 input parameters) +Function 344: GetImageColor() (3 input parameters) Name: GetImageColor Return type: Color Description: Get image pixel color at (x, y) position Param[1]: image (type: Image) Param[2]: x (type: int) Param[3]: y (type: int) -Function 343: ImageClearBackground() (2 input parameters) +Function 345: ImageClearBackground() (2 input parameters) Name: ImageClearBackground Return type: void Description: Clear image background with given color Param[1]: dst (type: Image *) Param[2]: color (type: Color) -Function 344: ImageDrawPixel() (4 input parameters) +Function 346: ImageDrawPixel() (4 input parameters) Name: ImageDrawPixel Return type: void Description: Draw pixel within an image @@ -3101,14 +3112,14 @@ Function 344: ImageDrawPixel() (4 input parameters) Param[2]: posX (type: int) Param[3]: posY (type: int) Param[4]: color (type: Color) -Function 345: ImageDrawPixelV() (3 input parameters) +Function 347: ImageDrawPixelV() (3 input parameters) Name: ImageDrawPixelV Return type: void Description: Draw pixel within an image (Vector version) Param[1]: dst (type: Image *) Param[2]: position (type: Vector2) Param[3]: color (type: Color) -Function 346: ImageDrawLine() (6 input parameters) +Function 348: ImageDrawLine() (6 input parameters) Name: ImageDrawLine Return type: void Description: Draw line within an image @@ -3118,7 +3129,7 @@ Function 346: ImageDrawLine() (6 input parameters) Param[4]: endPosX (type: int) Param[5]: endPosY (type: int) Param[6]: color (type: Color) -Function 347: ImageDrawLineV() (4 input parameters) +Function 349: ImageDrawLineV() (4 input parameters) Name: ImageDrawLineV Return type: void Description: Draw line within an image (Vector version) @@ -3126,7 +3137,7 @@ Function 347: ImageDrawLineV() (4 input parameters) Param[2]: start (type: Vector2) Param[3]: end (type: Vector2) Param[4]: color (type: Color) -Function 348: ImageDrawLineEx() (5 input parameters) +Function 350: ImageDrawLineEx() (5 input parameters) Name: ImageDrawLineEx Return type: void Description: Draw a line defining thickness within an image @@ -3135,7 +3146,7 @@ Function 348: ImageDrawLineEx() (5 input parameters) Param[3]: end (type: Vector2) Param[4]: thick (type: int) Param[5]: color (type: Color) -Function 349: ImageDrawCircle() (5 input parameters) +Function 351: ImageDrawCircle() (5 input parameters) Name: ImageDrawCircle Return type: void Description: Draw a filled circle within an image @@ -3144,7 +3155,7 @@ Function 349: ImageDrawCircle() (5 input parameters) Param[3]: centerY (type: int) Param[4]: radius (type: int) Param[5]: color (type: Color) -Function 350: ImageDrawCircleV() (4 input parameters) +Function 352: ImageDrawCircleV() (4 input parameters) Name: ImageDrawCircleV Return type: void Description: Draw a filled circle within an image (Vector version) @@ -3152,7 +3163,7 @@ Function 350: ImageDrawCircleV() (4 input parameters) Param[2]: center (type: Vector2) Param[3]: radius (type: int) Param[4]: color (type: Color) -Function 351: ImageDrawCircleLines() (5 input parameters) +Function 353: ImageDrawCircleLines() (5 input parameters) Name: ImageDrawCircleLines Return type: void Description: Draw circle outline within an image @@ -3161,7 +3172,7 @@ Function 351: ImageDrawCircleLines() (5 input parameters) Param[3]: centerY (type: int) Param[4]: radius (type: int) Param[5]: color (type: Color) -Function 352: ImageDrawCircleLinesV() (4 input parameters) +Function 354: ImageDrawCircleLinesV() (4 input parameters) Name: ImageDrawCircleLinesV Return type: void Description: Draw circle outline within an image (Vector version) @@ -3169,7 +3180,7 @@ Function 352: ImageDrawCircleLinesV() (4 input parameters) Param[2]: center (type: Vector2) Param[3]: radius (type: int) Param[4]: color (type: Color) -Function 353: ImageDrawRectangle() (6 input parameters) +Function 355: ImageDrawRectangle() (6 input parameters) Name: ImageDrawRectangle Return type: void Description: Draw rectangle within an image @@ -3179,7 +3190,7 @@ Function 353: ImageDrawRectangle() (6 input parameters) Param[4]: width (type: int) Param[5]: height (type: int) Param[6]: color (type: Color) -Function 354: ImageDrawRectangleV() (4 input parameters) +Function 356: ImageDrawRectangleV() (4 input parameters) Name: ImageDrawRectangleV Return type: void Description: Draw rectangle within an image (Vector version) @@ -3187,14 +3198,14 @@ Function 354: ImageDrawRectangleV() (4 input parameters) Param[2]: position (type: Vector2) Param[3]: size (type: Vector2) Param[4]: color (type: Color) -Function 355: ImageDrawRectangleRec() (3 input parameters) +Function 357: ImageDrawRectangleRec() (3 input parameters) Name: ImageDrawRectangleRec Return type: void Description: Draw rectangle within an image Param[1]: dst (type: Image *) Param[2]: rec (type: Rectangle) Param[3]: color (type: Color) -Function 356: ImageDrawRectangleLines() (4 input parameters) +Function 358: ImageDrawRectangleLines() (4 input parameters) Name: ImageDrawRectangleLines Return type: void Description: Draw rectangle lines within an image @@ -3202,7 +3213,7 @@ Function 356: ImageDrawRectangleLines() (4 input parameters) Param[2]: rec (type: Rectangle) Param[3]: thick (type: int) Param[4]: color (type: Color) -Function 357: ImageDrawTriangle() (5 input parameters) +Function 359: ImageDrawTriangle() (5 input parameters) Name: ImageDrawTriangle Return type: void Description: Draw triangle within an image @@ -3211,7 +3222,7 @@ Function 357: ImageDrawTriangle() (5 input parameters) Param[3]: v2 (type: Vector2) Param[4]: v3 (type: Vector2) Param[5]: color (type: Color) -Function 358: ImageDrawTriangleEx() (7 input parameters) +Function 360: ImageDrawTriangleEx() (7 input parameters) Name: ImageDrawTriangleEx Return type: void Description: Draw triangle with interpolated colors within an image @@ -3222,7 +3233,7 @@ Function 358: ImageDrawTriangleEx() (7 input parameters) Param[5]: c1 (type: Color) Param[6]: c2 (type: Color) Param[7]: c3 (type: Color) -Function 359: ImageDrawTriangleLines() (5 input parameters) +Function 361: ImageDrawTriangleLines() (5 input parameters) Name: ImageDrawTriangleLines Return type: void Description: Draw triangle outline within an image @@ -3231,7 +3242,7 @@ Function 359: ImageDrawTriangleLines() (5 input parameters) Param[3]: v2 (type: Vector2) Param[4]: v3 (type: Vector2) Param[5]: color (type: Color) -Function 360: ImageDrawTriangleFan() (4 input parameters) +Function 362: ImageDrawTriangleFan() (4 input parameters) Name: ImageDrawTriangleFan Return type: void Description: Draw a triangle fan defined by points within an image (first vertex is the center) @@ -3239,7 +3250,7 @@ Function 360: ImageDrawTriangleFan() (4 input parameters) Param[2]: points (type: const Vector2 *) Param[3]: pointCount (type: int) Param[4]: color (type: Color) -Function 361: ImageDrawTriangleStrip() (4 input parameters) +Function 363: ImageDrawTriangleStrip() (4 input parameters) Name: ImageDrawTriangleStrip Return type: void Description: Draw a triangle strip defined by points within an image @@ -3247,7 +3258,7 @@ Function 361: ImageDrawTriangleStrip() (4 input parameters) Param[2]: points (type: const Vector2 *) Param[3]: pointCount (type: int) Param[4]: color (type: Color) -Function 362: ImageDraw() (5 input parameters) +Function 364: ImageDraw() (5 input parameters) Name: ImageDraw Return type: void Description: Draw a source image within a destination image (tint applied to source) @@ -3256,7 +3267,7 @@ Function 362: ImageDraw() (5 input parameters) Param[3]: srcRec (type: Rectangle) Param[4]: dstRec (type: Rectangle) Param[5]: tint (type: Color) -Function 363: ImageDrawText() (6 input parameters) +Function 365: ImageDrawText() (6 input parameters) Name: ImageDrawText Return type: void Description: Draw text (using default font) within an image (destination) @@ -3266,7 +3277,7 @@ Function 363: ImageDrawText() (6 input parameters) Param[4]: posY (type: int) Param[5]: fontSize (type: int) Param[6]: color (type: Color) -Function 364: ImageDrawTextEx() (7 input parameters) +Function 366: ImageDrawTextEx() (7 input parameters) Name: ImageDrawTextEx Return type: void Description: Draw text (custom sprite font) within an image (destination) @@ -3277,79 +3288,79 @@ Function 364: ImageDrawTextEx() (7 input parameters) Param[5]: fontSize (type: float) Param[6]: spacing (type: float) Param[7]: tint (type: Color) -Function 365: LoadTexture() (1 input parameters) +Function 367: LoadTexture() (1 input parameters) Name: LoadTexture Return type: Texture2D Description: Load texture from file into GPU memory (VRAM) Param[1]: fileName (type: const char *) -Function 366: LoadTextureFromImage() (1 input parameters) +Function 368: LoadTextureFromImage() (1 input parameters) Name: LoadTextureFromImage Return type: Texture2D Description: Load texture from image data Param[1]: image (type: Image) -Function 367: LoadTextureCubemap() (2 input parameters) +Function 369: LoadTextureCubemap() (2 input parameters) Name: LoadTextureCubemap Return type: TextureCubemap Description: Load cubemap from image, multiple image cubemap layouts supported Param[1]: image (type: Image) Param[2]: layout (type: int) -Function 368: LoadRenderTexture() (2 input parameters) +Function 370: LoadRenderTexture() (2 input parameters) Name: LoadRenderTexture Return type: RenderTexture2D Description: Load texture for rendering (framebuffer) Param[1]: width (type: int) Param[2]: height (type: int) -Function 369: IsTextureValid() (1 input parameters) +Function 371: IsTextureValid() (1 input parameters) Name: IsTextureValid Return type: bool Description: Check if a texture is valid (loaded in GPU) Param[1]: texture (type: Texture2D) -Function 370: UnloadTexture() (1 input parameters) +Function 372: UnloadTexture() (1 input parameters) Name: UnloadTexture Return type: void Description: Unload texture from GPU memory (VRAM) Param[1]: texture (type: Texture2D) -Function 371: IsRenderTextureValid() (1 input parameters) +Function 373: IsRenderTextureValid() (1 input parameters) Name: IsRenderTextureValid Return type: bool Description: Check if a render texture is valid (loaded in GPU) Param[1]: target (type: RenderTexture2D) -Function 372: UnloadRenderTexture() (1 input parameters) +Function 374: UnloadRenderTexture() (1 input parameters) Name: UnloadRenderTexture Return type: void Description: Unload render texture from GPU memory (VRAM) Param[1]: target (type: RenderTexture2D) -Function 373: UpdateTexture() (2 input parameters) +Function 375: UpdateTexture() (2 input parameters) Name: UpdateTexture Return type: void Description: Update GPU texture with new data (pixels should be able to fill texture) Param[1]: texture (type: Texture2D) Param[2]: pixels (type: const void *) -Function 374: UpdateTextureRec() (3 input parameters) +Function 376: UpdateTextureRec() (3 input parameters) Name: UpdateTextureRec Return type: void Description: Update GPU texture rectangle with new data (pixels and rec should fit in texture) Param[1]: texture (type: Texture2D) Param[2]: rec (type: Rectangle) Param[3]: pixels (type: const void *) -Function 375: GenTextureMipmaps() (1 input parameters) +Function 377: GenTextureMipmaps() (1 input parameters) Name: GenTextureMipmaps Return type: void Description: Generate GPU mipmaps for a texture Param[1]: texture (type: Texture2D *) -Function 376: SetTextureFilter() (2 input parameters) +Function 378: SetTextureFilter() (2 input parameters) Name: SetTextureFilter Return type: void Description: Set texture scaling filter mode Param[1]: texture (type: Texture2D) Param[2]: filter (type: int) -Function 377: SetTextureWrap() (2 input parameters) +Function 379: SetTextureWrap() (2 input parameters) Name: SetTextureWrap Return type: void Description: Set texture wrapping mode Param[1]: texture (type: Texture2D) Param[2]: wrap (type: int) -Function 378: DrawTexture() (4 input parameters) +Function 380: DrawTexture() (4 input parameters) Name: DrawTexture Return type: void Description: Draw a Texture2D @@ -3357,14 +3368,14 @@ Function 378: DrawTexture() (4 input parameters) Param[2]: posX (type: int) Param[3]: posY (type: int) Param[4]: tint (type: Color) -Function 379: DrawTextureV() (3 input parameters) +Function 381: DrawTextureV() (3 input parameters) Name: DrawTextureV Return type: void Description: Draw a Texture2D with position defined as Vector2 Param[1]: texture (type: Texture2D) Param[2]: position (type: Vector2) Param[3]: tint (type: Color) -Function 380: DrawTextureEx() (5 input parameters) +Function 382: DrawTextureEx() (5 input parameters) Name: DrawTextureEx Return type: void Description: Draw a Texture2D with extended parameters @@ -3373,7 +3384,7 @@ Function 380: DrawTextureEx() (5 input parameters) Param[3]: rotation (type: float) Param[4]: scale (type: float) Param[5]: tint (type: Color) -Function 381: DrawTextureRec() (4 input parameters) +Function 383: DrawTextureRec() (4 input parameters) Name: DrawTextureRec Return type: void Description: Draw a part of a texture defined by a rectangle @@ -3381,7 +3392,7 @@ Function 381: DrawTextureRec() (4 input parameters) Param[2]: source (type: Rectangle) Param[3]: position (type: Vector2) Param[4]: tint (type: Color) -Function 382: DrawTexturePro() (6 input parameters) +Function 384: DrawTexturePro() (6 input parameters) Name: DrawTexturePro Return type: void Description: Draw a part of a texture defined by a rectangle with 'pro' parameters @@ -3391,7 +3402,7 @@ Function 382: DrawTexturePro() (6 input parameters) Param[4]: origin (type: Vector2) Param[5]: rotation (type: float) Param[6]: tint (type: Color) -Function 383: DrawTextureNPatch() (6 input parameters) +Function 385: DrawTextureNPatch() (6 input parameters) Name: DrawTextureNPatch Return type: void Description: Draws a texture (or part of it) that stretches or shrinks nicely @@ -3401,119 +3412,119 @@ Function 383: DrawTextureNPatch() (6 input parameters) Param[4]: origin (type: Vector2) Param[5]: rotation (type: float) Param[6]: tint (type: Color) -Function 384: ColorIsEqual() (2 input parameters) +Function 386: ColorIsEqual() (2 input parameters) Name: ColorIsEqual Return type: bool Description: Check if two colors are equal Param[1]: col1 (type: Color) Param[2]: col2 (type: Color) -Function 385: Fade() (2 input parameters) +Function 387: Fade() (2 input parameters) Name: Fade Return type: Color Description: Get color with alpha applied, alpha goes from 0.0f to 1.0f Param[1]: color (type: Color) Param[2]: alpha (type: float) -Function 386: ColorToInt() (1 input parameters) +Function 388: ColorToInt() (1 input parameters) Name: ColorToInt Return type: int Description: Get hexadecimal value for a Color (0xRRGGBBAA) Param[1]: color (type: Color) -Function 387: ColorNormalize() (1 input parameters) +Function 389: ColorNormalize() (1 input parameters) Name: ColorNormalize Return type: Vector4 Description: Get Color normalized as float [0..1] Param[1]: color (type: Color) -Function 388: ColorFromNormalized() (1 input parameters) +Function 390: ColorFromNormalized() (1 input parameters) Name: ColorFromNormalized Return type: Color Description: Get Color from normalized values [0..1] Param[1]: normalized (type: Vector4) -Function 389: ColorToHSV() (1 input parameters) +Function 391: ColorToHSV() (1 input parameters) Name: ColorToHSV Return type: Vector3 Description: Get HSV values for a Color, hue [0..360], saturation/value [0..1] Param[1]: color (type: Color) -Function 390: ColorFromHSV() (3 input parameters) +Function 392: ColorFromHSV() (3 input parameters) Name: ColorFromHSV Return type: Color Description: Get a Color from HSV values, hue [0..360], saturation/value [0..1] Param[1]: hue (type: float) Param[2]: saturation (type: float) Param[3]: value (type: float) -Function 391: ColorTint() (2 input parameters) +Function 393: ColorTint() (2 input parameters) Name: ColorTint Return type: Color Description: Get color multiplied with another color Param[1]: color (type: Color) Param[2]: tint (type: Color) -Function 392: ColorBrightness() (2 input parameters) +Function 394: ColorBrightness() (2 input parameters) Name: ColorBrightness Return type: Color Description: Get color with brightness correction, brightness factor goes from -1.0f to 1.0f Param[1]: color (type: Color) Param[2]: factor (type: float) -Function 393: ColorContrast() (2 input parameters) +Function 395: ColorContrast() (2 input parameters) Name: ColorContrast Return type: Color Description: Get color with contrast correction, contrast values between -1.0f and 1.0f Param[1]: color (type: Color) Param[2]: contrast (type: float) -Function 394: ColorAlpha() (2 input parameters) +Function 396: ColorAlpha() (2 input parameters) Name: ColorAlpha Return type: Color Description: Get color with alpha applied, alpha goes from 0.0f to 1.0f Param[1]: color (type: Color) Param[2]: alpha (type: float) -Function 395: ColorAlphaBlend() (3 input parameters) +Function 397: ColorAlphaBlend() (3 input parameters) Name: ColorAlphaBlend Return type: Color Description: Get src alpha-blended into dst color with tint Param[1]: dst (type: Color) Param[2]: src (type: Color) Param[3]: tint (type: Color) -Function 396: ColorLerp() (3 input parameters) +Function 398: ColorLerp() (3 input parameters) Name: ColorLerp Return type: Color Description: Get color lerp interpolation between two colors, factor [0.0f..1.0f] Param[1]: color1 (type: Color) Param[2]: color2 (type: Color) Param[3]: factor (type: float) -Function 397: GetColor() (1 input parameters) +Function 399: GetColor() (1 input parameters) Name: GetColor Return type: Color Description: Get Color structure from hexadecimal value Param[1]: hexValue (type: unsigned int) -Function 398: GetPixelColor() (2 input parameters) +Function 400: GetPixelColor() (2 input parameters) Name: GetPixelColor Return type: Color Description: Get Color from a source pixel pointer of certain format Param[1]: srcPtr (type: void *) Param[2]: format (type: int) -Function 399: SetPixelColor() (3 input parameters) +Function 401: SetPixelColor() (3 input parameters) Name: SetPixelColor Return type: void Description: Set color formatted into destination pixel pointer Param[1]: dstPtr (type: void *) Param[2]: color (type: Color) Param[3]: format (type: int) -Function 400: GetPixelDataSize() (3 input parameters) +Function 402: GetPixelDataSize() (3 input parameters) Name: GetPixelDataSize Return type: int Description: Get pixel data size in bytes for certain format Param[1]: width (type: int) Param[2]: height (type: int) Param[3]: format (type: int) -Function 401: GetFontDefault() (0 input parameters) +Function 403: GetFontDefault() (0 input parameters) Name: GetFontDefault Return type: Font Description: Get the default Font No input parameters -Function 402: LoadFont() (1 input parameters) +Function 404: LoadFont() (1 input parameters) Name: LoadFont Return type: Font Description: Load font from file into GPU memory (VRAM) Param[1]: fileName (type: const char *) -Function 403: LoadFontEx() (4 input parameters) +Function 405: LoadFontEx() (4 input parameters) Name: LoadFontEx Return type: Font Description: Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height @@ -3521,14 +3532,14 @@ Function 403: LoadFontEx() (4 input parameters) Param[2]: fontSize (type: int) Param[3]: codepoints (type: const int *) Param[4]: codepointCount (type: int) -Function 404: LoadFontFromImage() (3 input parameters) +Function 406: LoadFontFromImage() (3 input parameters) Name: LoadFontFromImage Return type: Font Description: Load font from Image (XNA style) Param[1]: image (type: Image) Param[2]: key (type: Color) Param[3]: firstChar (type: int) -Function 405: LoadFontFromMemory() (6 input parameters) +Function 407: LoadFontFromMemory() (6 input parameters) Name: LoadFontFromMemory Return type: Font Description: Load font from memory buffer, fileType refers to extension: i.e. '.ttf' @@ -3538,12 +3549,12 @@ Function 405: LoadFontFromMemory() (6 input parameters) Param[4]: fontSize (type: int) Param[5]: codepoints (type: const int *) Param[6]: codepointCount (type: int) -Function 406: IsFontValid() (1 input parameters) +Function 408: IsFontValid() (1 input parameters) Name: IsFontValid Return type: bool Description: Check if a font is valid (font data loaded, WARNING: GPU texture not checked) Param[1]: font (type: Font) -Function 407: LoadFontData() (7 input parameters) +Function 409: LoadFontData() (7 input parameters) Name: LoadFontData Return type: GlyphInfo * Description: Load font data for further use @@ -3554,7 +3565,7 @@ Function 407: LoadFontData() (7 input parameters) Param[5]: codepointCount (type: int) Param[6]: type (type: int) Param[7]: glyphCount (type: int *) -Function 408: GenImageFontAtlas() (6 input parameters) +Function 410: GenImageFontAtlas() (6 input parameters) Name: GenImageFontAtlas Return type: Image Description: Generate image font atlas using chars info @@ -3564,30 +3575,30 @@ Function 408: GenImageFontAtlas() (6 input parameters) Param[4]: fontSize (type: int) Param[5]: padding (type: int) Param[6]: packMethod (type: int) -Function 409: UnloadFontData() (2 input parameters) +Function 411: UnloadFontData() (2 input parameters) Name: UnloadFontData Return type: void Description: Unload font chars info data (RAM) Param[1]: glyphs (type: GlyphInfo *) Param[2]: glyphCount (type: int) -Function 410: UnloadFont() (1 input parameters) +Function 412: UnloadFont() (1 input parameters) Name: UnloadFont Return type: void Description: Unload font from GPU memory (VRAM) Param[1]: font (type: Font) -Function 411: ExportFontAsCode() (2 input parameters) +Function 413: ExportFontAsCode() (2 input parameters) Name: ExportFontAsCode Return type: bool Description: Export font as code file, returns true on success Param[1]: font (type: Font) Param[2]: fileName (type: const char *) -Function 412: DrawFPS() (2 input parameters) +Function 414: DrawFPS() (2 input parameters) Name: DrawFPS Return type: void Description: Draw current FPS Param[1]: posX (type: int) Param[2]: posY (type: int) -Function 413: DrawText() (5 input parameters) +Function 415: DrawText() (5 input parameters) Name: DrawText Return type: void Description: Draw text (using default font) @@ -3596,7 +3607,7 @@ Function 413: DrawText() (5 input parameters) Param[3]: posY (type: int) Param[4]: fontSize (type: int) Param[5]: color (type: Color) -Function 414: DrawTextEx() (6 input parameters) +Function 416: DrawTextEx() (6 input parameters) Name: DrawTextEx Return type: void Description: Draw text using font and additional parameters @@ -3606,7 +3617,7 @@ Function 414: DrawTextEx() (6 input parameters) Param[4]: fontSize (type: float) Param[5]: spacing (type: float) Param[6]: tint (type: Color) -Function 415: DrawTextPro() (8 input parameters) +Function 417: DrawTextPro() (8 input parameters) Name: DrawTextPro Return type: void Description: Draw text using Font and pro parameters (rotation) @@ -3618,7 +3629,7 @@ Function 415: DrawTextPro() (8 input parameters) Param[6]: fontSize (type: float) Param[7]: spacing (type: float) Param[8]: tint (type: Color) -Function 416: DrawTextCodepoint() (5 input parameters) +Function 418: DrawTextCodepoint() (5 input parameters) Name: DrawTextCodepoint Return type: void Description: Draw one character (codepoint) @@ -3627,7 +3638,7 @@ Function 416: DrawTextCodepoint() (5 input parameters) Param[3]: position (type: Vector2) Param[4]: fontSize (type: float) Param[5]: tint (type: Color) -Function 417: DrawTextCodepoints() (7 input parameters) +Function 419: DrawTextCodepoints() (7 input parameters) Name: DrawTextCodepoints Return type: void Description: Draw multiple character (codepoint) @@ -3638,18 +3649,18 @@ Function 417: DrawTextCodepoints() (7 input parameters) Param[5]: fontSize (type: float) Param[6]: spacing (type: float) Param[7]: tint (type: Color) -Function 418: SetTextLineSpacing() (1 input parameters) +Function 420: SetTextLineSpacing() (1 input parameters) Name: SetTextLineSpacing Return type: void Description: Set vertical line spacing when drawing with line-breaks Param[1]: spacing (type: int) -Function 419: MeasureText() (2 input parameters) +Function 421: MeasureText() (2 input parameters) Name: MeasureText Return type: int Description: Measure string width for default font Param[1]: text (type: const char *) Param[2]: fontSize (type: int) -Function 420: MeasureTextEx() (4 input parameters) +Function 422: MeasureTextEx() (4 input parameters) Name: MeasureTextEx Return type: Vector2 Description: Measure string size for Font @@ -3657,137 +3668,137 @@ Function 420: MeasureTextEx() (4 input parameters) Param[2]: text (type: const char *) Param[3]: fontSize (type: float) Param[4]: spacing (type: float) -Function 421: GetGlyphIndex() (2 input parameters) +Function 423: GetGlyphIndex() (2 input parameters) Name: GetGlyphIndex Return type: int Description: Get glyph index position in font for a codepoint (unicode character), fallback to '?' if not found Param[1]: font (type: Font) Param[2]: codepoint (type: int) -Function 422: GetGlyphInfo() (2 input parameters) +Function 424: GetGlyphInfo() (2 input parameters) Name: GetGlyphInfo Return type: GlyphInfo Description: Get glyph font info data for a codepoint (unicode character), fallback to '?' if not found Param[1]: font (type: Font) Param[2]: codepoint (type: int) -Function 423: GetGlyphAtlasRec() (2 input parameters) +Function 425: GetGlyphAtlasRec() (2 input parameters) Name: GetGlyphAtlasRec Return type: Rectangle Description: Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found Param[1]: font (type: Font) Param[2]: codepoint (type: int) -Function 424: LoadUTF8() (2 input parameters) +Function 426: LoadUTF8() (2 input parameters) Name: LoadUTF8 Return type: char * Description: Load UTF-8 text encoded from codepoints array Param[1]: codepoints (type: const int *) Param[2]: length (type: int) -Function 425: UnloadUTF8() (1 input parameters) +Function 427: UnloadUTF8() (1 input parameters) Name: UnloadUTF8 Return type: void Description: Unload UTF-8 text encoded from codepoints array Param[1]: text (type: char *) -Function 426: LoadCodepoints() (2 input parameters) +Function 428: LoadCodepoints() (2 input parameters) Name: LoadCodepoints Return type: int * Description: Load all codepoints from a UTF-8 text string, codepoints count returned by parameter Param[1]: text (type: const char *) Param[2]: count (type: int *) -Function 427: UnloadCodepoints() (1 input parameters) +Function 429: UnloadCodepoints() (1 input parameters) Name: UnloadCodepoints Return type: void Description: Unload codepoints data from memory Param[1]: codepoints (type: int *) -Function 428: GetCodepointCount() (1 input parameters) +Function 430: GetCodepointCount() (1 input parameters) Name: GetCodepointCount Return type: int Description: Get total number of codepoints in a UTF-8 encoded string Param[1]: text (type: const char *) -Function 429: GetCodepoint() (2 input parameters) +Function 431: GetCodepoint() (2 input parameters) Name: GetCodepoint Return type: int Description: Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure Param[1]: text (type: const char *) Param[2]: codepointSize (type: int *) -Function 430: GetCodepointNext() (2 input parameters) +Function 432: GetCodepointNext() (2 input parameters) Name: GetCodepointNext Return type: int Description: Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure Param[1]: text (type: const char *) Param[2]: codepointSize (type: int *) -Function 431: GetCodepointPrevious() (2 input parameters) +Function 433: GetCodepointPrevious() (2 input parameters) Name: GetCodepointPrevious Return type: int Description: Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure Param[1]: text (type: const char *) Param[2]: codepointSize (type: int *) -Function 432: CodepointToUTF8() (2 input parameters) +Function 434: CodepointToUTF8() (2 input parameters) Name: CodepointToUTF8 Return type: const char * Description: Encode one codepoint into UTF-8 byte array (array length returned as parameter) Param[1]: codepoint (type: int) Param[2]: utf8Size (type: int *) -Function 433: LoadTextLines() (2 input parameters) +Function 435: LoadTextLines() (2 input parameters) Name: LoadTextLines Return type: char ** Description: Load text as separate lines ('\n') Param[1]: text (type: const char *) Param[2]: count (type: int *) -Function 434: UnloadTextLines() (2 input parameters) +Function 436: UnloadTextLines() (2 input parameters) Name: UnloadTextLines Return type: void Description: Unload text lines Param[1]: text (type: char **) Param[2]: lineCount (type: int) -Function 435: TextCopy() (2 input parameters) +Function 437: TextCopy() (2 input parameters) Name: TextCopy Return type: int Description: Copy one string to another, returns bytes copied Param[1]: dst (type: char *) Param[2]: src (type: const char *) -Function 436: TextIsEqual() (2 input parameters) +Function 438: TextIsEqual() (2 input parameters) Name: TextIsEqual Return type: bool Description: Check if two text string are equal Param[1]: text1 (type: const char *) Param[2]: text2 (type: const char *) -Function 437: TextLength() (1 input parameters) +Function 439: TextLength() (1 input parameters) Name: TextLength Return type: unsigned int Description: Get text length, checks for '\0' ending Param[1]: text (type: const char *) -Function 438: TextFormat() (2 input parameters) +Function 440: TextFormat() (2 input parameters) Name: TextFormat Return type: const char * Description: Text formatting with variables (sprintf() style) Param[1]: text (type: const char *) Param[2]: args (type: ...) -Function 439: TextSubtext() (3 input parameters) +Function 441: TextSubtext() (3 input parameters) Name: TextSubtext Return type: const char * Description: Get a piece of a text string Param[1]: text (type: const char *) Param[2]: position (type: int) Param[3]: length (type: int) -Function 440: TextRemoveSpaces() (1 input parameters) +Function 442: TextRemoveSpaces() (1 input parameters) Name: TextRemoveSpaces Return type: const char * Description: Remove text spaces, concat words Param[1]: text (type: const char *) -Function 441: GetTextBetween() (3 input parameters) +Function 443: GetTextBetween() (3 input parameters) Name: GetTextBetween Return type: char * Description: Get text between two strings Param[1]: text (type: const char *) Param[2]: begin (type: const char *) Param[3]: end (type: const char *) -Function 442: TextReplace() (3 input parameters) +Function 444: TextReplace() (3 input parameters) Name: TextReplace Return type: char * Description: Replace text string (WARNING: memory must be freed!) Param[1]: text (type: const char *) Param[2]: search (type: const char *) Param[3]: replacement (type: const char *) -Function 443: TextReplaceBetween() (4 input parameters) +Function 445: TextReplaceBetween() (4 input parameters) Name: TextReplaceBetween Return type: char * Description: Replace text between two specific strings (WARNING: memory must be freed!) @@ -3795,89 +3806,89 @@ Function 443: TextReplaceBetween() (4 input parameters) Param[2]: begin (type: const char *) Param[3]: end (type: const char *) Param[4]: replacement (type: const char *) -Function 444: TextInsert() (3 input parameters) +Function 446: TextInsert() (3 input parameters) Name: TextInsert Return type: char * Description: Insert text in a position (WARNING: memory must be freed!) Param[1]: text (type: const char *) Param[2]: insert (type: const char *) Param[3]: position (type: int) -Function 445: TextJoin() (3 input parameters) +Function 447: TextJoin() (3 input parameters) Name: TextJoin Return type: char * Description: Join text strings with delimiter Param[1]: textList (type: char **) Param[2]: count (type: int) Param[3]: delimiter (type: const char *) -Function 446: TextSplit() (3 input parameters) +Function 448: TextSplit() (3 input parameters) Name: TextSplit Return type: char ** Description: Split text into multiple strings, using MAX_TEXTSPLIT_COUNT static strings Param[1]: text (type: const char *) Param[2]: delimiter (type: char) Param[3]: count (type: int *) -Function 447: TextAppend() (3 input parameters) +Function 449: TextAppend() (3 input parameters) Name: TextAppend Return type: void Description: Append text at specific position and move cursor Param[1]: text (type: char *) Param[2]: append (type: const char *) Param[3]: position (type: int *) -Function 448: TextFindIndex() (2 input parameters) +Function 450: TextFindIndex() (2 input parameters) Name: TextFindIndex Return type: int Description: Find first text occurrence within a string, -1 if not found Param[1]: text (type: const char *) Param[2]: search (type: const char *) -Function 449: TextToUpper() (1 input parameters) +Function 451: TextToUpper() (1 input parameters) Name: TextToUpper Return type: char * Description: Get upper case version of provided string Param[1]: text (type: const char *) -Function 450: TextToLower() (1 input parameters) +Function 452: TextToLower() (1 input parameters) Name: TextToLower Return type: char * Description: Get lower case version of provided string Param[1]: text (type: const char *) -Function 451: TextToPascal() (1 input parameters) +Function 453: TextToPascal() (1 input parameters) Name: TextToPascal Return type: char * Description: Get Pascal case notation version of provided string Param[1]: text (type: const char *) -Function 452: TextToSnake() (1 input parameters) +Function 454: TextToSnake() (1 input parameters) Name: TextToSnake Return type: char * Description: Get Snake case notation version of provided string Param[1]: text (type: const char *) -Function 453: TextToCamel() (1 input parameters) +Function 455: TextToCamel() (1 input parameters) Name: TextToCamel Return type: char * Description: Get Camel case notation version of provided string Param[1]: text (type: const char *) -Function 454: TextToInteger() (1 input parameters) +Function 456: TextToInteger() (1 input parameters) Name: TextToInteger Return type: int Description: Get integer value from text Param[1]: text (type: const char *) -Function 455: TextToFloat() (1 input parameters) +Function 457: TextToFloat() (1 input parameters) Name: TextToFloat Return type: float Description: Get float value from text Param[1]: text (type: const char *) -Function 456: DrawLine3D() (3 input parameters) +Function 458: DrawLine3D() (3 input parameters) Name: DrawLine3D Return type: void Description: Draw a line in 3D world space Param[1]: startPos (type: Vector3) Param[2]: endPos (type: Vector3) Param[3]: color (type: Color) -Function 457: DrawPoint3D() (2 input parameters) +Function 459: DrawPoint3D() (2 input parameters) Name: DrawPoint3D Return type: void Description: Draw a point in 3D space, actually a small line Param[1]: position (type: Vector3) Param[2]: color (type: Color) -Function 458: DrawCircle3D() (5 input parameters) +Function 460: DrawCircle3D() (5 input parameters) Name: DrawCircle3D Return type: void Description: Draw a circle in 3D world space @@ -3886,7 +3897,7 @@ Function 458: DrawCircle3D() (5 input parameters) Param[3]: rotationAxis (type: Vector3) Param[4]: rotationAngle (type: float) Param[5]: color (type: Color) -Function 459: DrawTriangle3D() (4 input parameters) +Function 461: DrawTriangle3D() (4 input parameters) Name: DrawTriangle3D Return type: void Description: Draw a color-filled triangle (vertex in counter-clockwise order!) @@ -3894,14 +3905,14 @@ Function 459: DrawTriangle3D() (4 input parameters) Param[2]: v2 (type: Vector3) Param[3]: v3 (type: Vector3) Param[4]: color (type: Color) -Function 460: DrawTriangleStrip3D() (3 input parameters) +Function 462: DrawTriangleStrip3D() (3 input parameters) Name: DrawTriangleStrip3D Return type: void Description: Draw a triangle strip defined by points Param[1]: points (type: const Vector3 *) Param[2]: pointCount (type: int) Param[3]: color (type: Color) -Function 461: DrawCube() (5 input parameters) +Function 463: DrawCube() (5 input parameters) Name: DrawCube Return type: void Description: Draw cube @@ -3910,14 +3921,14 @@ Function 461: DrawCube() (5 input parameters) Param[3]: height (type: float) Param[4]: length (type: float) Param[5]: color (type: Color) -Function 462: DrawCubeV() (3 input parameters) +Function 464: DrawCubeV() (3 input parameters) Name: DrawCubeV Return type: void Description: Draw cube (Vector version) Param[1]: position (type: Vector3) Param[2]: size (type: Vector3) Param[3]: color (type: Color) -Function 463: DrawCubeWires() (5 input parameters) +Function 465: DrawCubeWires() (5 input parameters) Name: DrawCubeWires Return type: void Description: Draw cube wires @@ -3926,21 +3937,21 @@ Function 463: DrawCubeWires() (5 input parameters) Param[3]: height (type: float) Param[4]: length (type: float) Param[5]: color (type: Color) -Function 464: DrawCubeWiresV() (3 input parameters) +Function 466: DrawCubeWiresV() (3 input parameters) Name: DrawCubeWiresV Return type: void Description: Draw cube wires (Vector version) Param[1]: position (type: Vector3) Param[2]: size (type: Vector3) Param[3]: color (type: Color) -Function 465: DrawSphere() (3 input parameters) +Function 467: DrawSphere() (3 input parameters) Name: DrawSphere Return type: void Description: Draw sphere Param[1]: centerPos (type: Vector3) Param[2]: radius (type: float) Param[3]: color (type: Color) -Function 466: DrawSphereEx() (5 input parameters) +Function 468: DrawSphereEx() (5 input parameters) Name: DrawSphereEx Return type: void Description: Draw sphere with extended parameters @@ -3949,7 +3960,7 @@ Function 466: DrawSphereEx() (5 input parameters) Param[3]: rings (type: int) Param[4]: slices (type: int) Param[5]: color (type: Color) -Function 467: DrawSphereWires() (5 input parameters) +Function 469: DrawSphereWires() (5 input parameters) Name: DrawSphereWires Return type: void Description: Draw sphere wires @@ -3958,7 +3969,7 @@ Function 467: DrawSphereWires() (5 input parameters) Param[3]: rings (type: int) Param[4]: slices (type: int) Param[5]: color (type: Color) -Function 468: DrawCylinder() (6 input parameters) +Function 470: DrawCylinder() (6 input parameters) Name: DrawCylinder Return type: void Description: Draw a cylinder/cone @@ -3968,7 +3979,7 @@ Function 468: DrawCylinder() (6 input parameters) Param[4]: height (type: float) Param[5]: slices (type: int) Param[6]: color (type: Color) -Function 469: DrawCylinderEx() (6 input parameters) +Function 471: DrawCylinderEx() (6 input parameters) Name: DrawCylinderEx Return type: void Description: Draw a cylinder with base at startPos and top at endPos @@ -3978,7 +3989,7 @@ Function 469: DrawCylinderEx() (6 input parameters) Param[4]: endRadius (type: float) Param[5]: sides (type: int) Param[6]: color (type: Color) -Function 470: DrawCylinderWires() (6 input parameters) +Function 472: DrawCylinderWires() (6 input parameters) Name: DrawCylinderWires Return type: void Description: Draw a cylinder/cone wires @@ -3988,7 +3999,7 @@ Function 470: DrawCylinderWires() (6 input parameters) Param[4]: height (type: float) Param[5]: slices (type: int) Param[6]: color (type: Color) -Function 471: DrawCylinderWiresEx() (6 input parameters) +Function 473: DrawCylinderWiresEx() (6 input parameters) Name: DrawCylinderWiresEx Return type: void Description: Draw a cylinder wires with base at startPos and top at endPos @@ -3998,7 +4009,7 @@ Function 471: DrawCylinderWiresEx() (6 input parameters) Param[4]: endRadius (type: float) Param[5]: sides (type: int) Param[6]: color (type: Color) -Function 472: DrawCapsule() (6 input parameters) +Function 474: DrawCapsule() (6 input parameters) Name: DrawCapsule Return type: void Description: Draw a capsule with the center of its sphere caps at startPos and endPos @@ -4008,7 +4019,7 @@ Function 472: DrawCapsule() (6 input parameters) Param[4]: slices (type: int) Param[5]: rings (type: int) Param[6]: color (type: Color) -Function 473: DrawCapsuleWires() (6 input parameters) +Function 475: DrawCapsuleWires() (6 input parameters) Name: DrawCapsuleWires Return type: void Description: Draw capsule wireframe with the center of its sphere caps at startPos and endPos @@ -4018,51 +4029,51 @@ Function 473: DrawCapsuleWires() (6 input parameters) Param[4]: slices (type: int) Param[5]: rings (type: int) Param[6]: color (type: Color) -Function 474: DrawPlane() (3 input parameters) +Function 476: DrawPlane() (3 input parameters) Name: DrawPlane Return type: void Description: Draw a plane XZ Param[1]: centerPos (type: Vector3) Param[2]: size (type: Vector2) Param[3]: color (type: Color) -Function 475: DrawRay() (2 input parameters) +Function 477: DrawRay() (2 input parameters) Name: DrawRay Return type: void Description: Draw a ray line Param[1]: ray (type: Ray) Param[2]: color (type: Color) -Function 476: DrawGrid() (2 input parameters) +Function 478: DrawGrid() (2 input parameters) Name: DrawGrid Return type: void Description: Draw a grid (centered at (0, 0, 0)) Param[1]: slices (type: int) Param[2]: spacing (type: float) -Function 477: LoadModel() (1 input parameters) +Function 479: LoadModel() (1 input parameters) Name: LoadModel Return type: Model Description: Load model from files (meshes and materials) Param[1]: fileName (type: const char *) -Function 478: LoadModelFromMesh() (1 input parameters) +Function 480: LoadModelFromMesh() (1 input parameters) Name: LoadModelFromMesh Return type: Model Description: Load model from generated mesh (default material) Param[1]: mesh (type: Mesh) -Function 479: IsModelValid() (1 input parameters) +Function 481: IsModelValid() (1 input parameters) Name: IsModelValid Return type: bool Description: Check if a model is valid (loaded in GPU, VAO/VBOs) Param[1]: model (type: Model) -Function 480: UnloadModel() (1 input parameters) +Function 482: UnloadModel() (1 input parameters) Name: UnloadModel Return type: void Description: Unload model (including meshes) from memory (RAM and/or VRAM) Param[1]: model (type: Model) -Function 481: GetModelBoundingBox() (1 input parameters) +Function 483: GetModelBoundingBox() (1 input parameters) Name: GetModelBoundingBox Return type: BoundingBox Description: Compute model bounding box limits (considers all meshes) Param[1]: model (type: Model) -Function 482: DrawModel() (4 input parameters) +Function 484: DrawModel() (4 input parameters) Name: DrawModel Return type: void Description: Draw a model (with texture if set) @@ -4070,7 +4081,7 @@ Function 482: DrawModel() (4 input parameters) Param[2]: position (type: Vector3) Param[3]: scale (type: float) Param[4]: tint (type: Color) -Function 483: DrawModelEx() (6 input parameters) +Function 485: DrawModelEx() (6 input parameters) Name: DrawModelEx Return type: void Description: Draw a model with extended parameters @@ -4080,7 +4091,7 @@ Function 483: DrawModelEx() (6 input parameters) Param[4]: rotationAngle (type: float) Param[5]: scale (type: Vector3) Param[6]: tint (type: Color) -Function 484: DrawModelWires() (4 input parameters) +Function 486: DrawModelWires() (4 input parameters) Name: DrawModelWires Return type: void Description: Draw a model wires (with texture if set) @@ -4088,7 +4099,7 @@ Function 484: DrawModelWires() (4 input parameters) Param[2]: position (type: Vector3) Param[3]: scale (type: float) Param[4]: tint (type: Color) -Function 485: DrawModelWiresEx() (6 input parameters) +Function 487: DrawModelWiresEx() (6 input parameters) Name: DrawModelWiresEx Return type: void Description: Draw a model wires (with texture if set) with extended parameters @@ -4098,7 +4109,7 @@ Function 485: DrawModelWiresEx() (6 input parameters) Param[4]: rotationAngle (type: float) Param[5]: scale (type: Vector3) Param[6]: tint (type: Color) -Function 486: DrawModelPoints() (4 input parameters) +Function 488: DrawModelPoints() (4 input parameters) Name: DrawModelPoints Return type: void Description: Draw a model as points @@ -4106,7 +4117,7 @@ Function 486: DrawModelPoints() (4 input parameters) Param[2]: position (type: Vector3) Param[3]: scale (type: float) Param[4]: tint (type: Color) -Function 487: DrawModelPointsEx() (6 input parameters) +Function 489: DrawModelPointsEx() (6 input parameters) Name: DrawModelPointsEx Return type: void Description: Draw a model as points with extended parameters @@ -4116,13 +4127,13 @@ Function 487: DrawModelPointsEx() (6 input parameters) Param[4]: rotationAngle (type: float) Param[5]: scale (type: Vector3) Param[6]: tint (type: Color) -Function 488: DrawBoundingBox() (2 input parameters) +Function 490: DrawBoundingBox() (2 input parameters) Name: DrawBoundingBox Return type: void Description: Draw bounding box (wires) Param[1]: box (type: BoundingBox) Param[2]: color (type: Color) -Function 489: DrawBillboard() (5 input parameters) +Function 491: DrawBillboard() (5 input parameters) Name: DrawBillboard Return type: void Description: Draw a billboard texture @@ -4131,7 +4142,7 @@ Function 489: DrawBillboard() (5 input parameters) Param[3]: position (type: Vector3) Param[4]: scale (type: float) Param[5]: tint (type: Color) -Function 490: DrawBillboardRec() (6 input parameters) +Function 492: DrawBillboardRec() (6 input parameters) Name: DrawBillboardRec Return type: void Description: Draw a billboard texture defined by source @@ -4141,7 +4152,7 @@ Function 490: DrawBillboardRec() (6 input parameters) Param[4]: position (type: Vector3) Param[5]: size (type: Vector2) Param[6]: tint (type: Color) -Function 491: DrawBillboardPro() (9 input parameters) +Function 493: DrawBillboardPro() (9 input parameters) Name: DrawBillboardPro Return type: void Description: Draw a billboard texture defined by source and rotation @@ -4154,13 +4165,13 @@ Function 491: DrawBillboardPro() (9 input parameters) Param[7]: origin (type: Vector2) Param[8]: rotation (type: float) Param[9]: tint (type: Color) -Function 492: UploadMesh() (2 input parameters) +Function 494: UploadMesh() (2 input parameters) Name: UploadMesh Return type: void Description: Upload mesh vertex data in GPU and provide VAO/VBO ids Param[1]: mesh (type: Mesh *) Param[2]: dynamic (type: bool) -Function 493: UpdateMeshBuffer() (5 input parameters) +Function 495: UpdateMeshBuffer() (5 input parameters) Name: UpdateMeshBuffer Return type: void Description: Update mesh vertex data in GPU for a specific buffer index @@ -4169,19 +4180,19 @@ Function 493: UpdateMeshBuffer() (5 input parameters) Param[3]: data (type: const void *) Param[4]: dataSize (type: int) Param[5]: offset (type: int) -Function 494: UnloadMesh() (1 input parameters) +Function 496: UnloadMesh() (1 input parameters) Name: UnloadMesh Return type: void Description: Unload mesh data from CPU and GPU Param[1]: mesh (type: Mesh) -Function 495: DrawMesh() (3 input parameters) +Function 497: DrawMesh() (3 input parameters) Name: DrawMesh Return type: void Description: Draw a 3d mesh with material and transform Param[1]: mesh (type: Mesh) Param[2]: material (type: Material) Param[3]: transform (type: Matrix) -Function 496: DrawMeshInstanced() (4 input parameters) +Function 498: DrawMeshInstanced() (4 input parameters) Name: DrawMeshInstanced Return type: void Description: Draw multiple mesh instances with material and different transforms @@ -4189,35 +4200,35 @@ Function 496: DrawMeshInstanced() (4 input parameters) Param[2]: material (type: Material) Param[3]: transforms (type: const Matrix *) Param[4]: instances (type: int) -Function 497: GetMeshBoundingBox() (1 input parameters) +Function 499: GetMeshBoundingBox() (1 input parameters) Name: GetMeshBoundingBox Return type: BoundingBox Description: Compute mesh bounding box limits Param[1]: mesh (type: Mesh) -Function 498: GenMeshTangents() (1 input parameters) +Function 500: GenMeshTangents() (1 input parameters) Name: GenMeshTangents Return type: void Description: Compute mesh tangents Param[1]: mesh (type: Mesh *) -Function 499: ExportMesh() (2 input parameters) +Function 501: ExportMesh() (2 input parameters) Name: ExportMesh Return type: bool Description: Export mesh data to file, returns true on success Param[1]: mesh (type: Mesh) Param[2]: fileName (type: const char *) -Function 500: ExportMeshAsCode() (2 input parameters) +Function 502: ExportMeshAsCode() (2 input parameters) Name: ExportMeshAsCode Return type: bool Description: Export mesh as code file (.h) defining multiple arrays of vertex attributes Param[1]: mesh (type: Mesh) Param[2]: fileName (type: const char *) -Function 501: GenMeshPoly() (2 input parameters) +Function 503: GenMeshPoly() (2 input parameters) Name: GenMeshPoly Return type: Mesh Description: Generate polygonal mesh Param[1]: sides (type: int) Param[2]: radius (type: float) -Function 502: GenMeshPlane() (4 input parameters) +Function 504: GenMeshPlane() (4 input parameters) Name: GenMeshPlane Return type: Mesh Description: Generate plane mesh (with subdivisions) @@ -4225,42 +4236,42 @@ Function 502: GenMeshPlane() (4 input parameters) Param[2]: length (type: float) Param[3]: resX (type: int) Param[4]: resZ (type: int) -Function 503: GenMeshCube() (3 input parameters) +Function 505: GenMeshCube() (3 input parameters) Name: GenMeshCube Return type: Mesh Description: Generate cuboid mesh Param[1]: width (type: float) Param[2]: height (type: float) Param[3]: length (type: float) -Function 504: GenMeshSphere() (3 input parameters) +Function 506: GenMeshSphere() (3 input parameters) Name: GenMeshSphere Return type: Mesh Description: Generate sphere mesh (standard sphere) Param[1]: radius (type: float) Param[2]: rings (type: int) Param[3]: slices (type: int) -Function 505: GenMeshHemiSphere() (3 input parameters) +Function 507: GenMeshHemiSphere() (3 input parameters) Name: GenMeshHemiSphere Return type: Mesh Description: Generate half-sphere mesh (no bottom cap) Param[1]: radius (type: float) Param[2]: rings (type: int) Param[3]: slices (type: int) -Function 506: GenMeshCylinder() (3 input parameters) +Function 508: GenMeshCylinder() (3 input parameters) Name: GenMeshCylinder Return type: Mesh Description: Generate cylinder mesh Param[1]: radius (type: float) Param[2]: height (type: float) Param[3]: slices (type: int) -Function 507: GenMeshCone() (3 input parameters) +Function 509: GenMeshCone() (3 input parameters) Name: GenMeshCone Return type: Mesh Description: Generate cone/pyramid mesh Param[1]: radius (type: float) Param[2]: height (type: float) Param[3]: slices (type: int) -Function 508: GenMeshTorus() (4 input parameters) +Function 510: GenMeshTorus() (4 input parameters) Name: GenMeshTorus Return type: Mesh Description: Generate torus mesh @@ -4268,7 +4279,7 @@ Function 508: GenMeshTorus() (4 input parameters) Param[2]: size (type: float) Param[3]: radSeg (type: int) Param[4]: sides (type: int) -Function 509: GenMeshKnot() (4 input parameters) +Function 511: GenMeshKnot() (4 input parameters) Name: GenMeshKnot Return type: Mesh Description: Generate trefoil knot mesh @@ -4276,91 +4287,91 @@ Function 509: GenMeshKnot() (4 input parameters) Param[2]: size (type: float) Param[3]: radSeg (type: int) Param[4]: sides (type: int) -Function 510: GenMeshHeightmap() (2 input parameters) +Function 512: GenMeshHeightmap() (2 input parameters) Name: GenMeshHeightmap Return type: Mesh Description: Generate heightmap mesh from image data Param[1]: heightmap (type: Image) Param[2]: size (type: Vector3) -Function 511: GenMeshCubicmap() (2 input parameters) +Function 513: GenMeshCubicmap() (2 input parameters) Name: GenMeshCubicmap Return type: Mesh Description: Generate cubes-based map mesh from image data Param[1]: cubicmap (type: Image) Param[2]: cubeSize (type: Vector3) -Function 512: LoadMaterials() (2 input parameters) +Function 514: LoadMaterials() (2 input parameters) Name: LoadMaterials Return type: Material * Description: Load materials from model file Param[1]: fileName (type: const char *) Param[2]: materialCount (type: int *) -Function 513: LoadMaterialDefault() (0 input parameters) +Function 515: LoadMaterialDefault() (0 input parameters) Name: LoadMaterialDefault Return type: Material Description: Load default material (Supports: DIFFUSE, SPECULAR, NORMAL maps) No input parameters -Function 514: IsMaterialValid() (1 input parameters) +Function 516: IsMaterialValid() (1 input parameters) Name: IsMaterialValid Return type: bool Description: Check if a material is valid (shader assigned, map textures loaded in GPU) Param[1]: material (type: Material) -Function 515: UnloadMaterial() (1 input parameters) +Function 517: UnloadMaterial() (1 input parameters) Name: UnloadMaterial Return type: void Description: Unload material from GPU memory (VRAM) Param[1]: material (type: Material) -Function 516: SetMaterialTexture() (3 input parameters) +Function 518: SetMaterialTexture() (3 input parameters) Name: SetMaterialTexture Return type: void Description: Set texture for a material map type (MATERIAL_MAP_DIFFUSE, MATERIAL_MAP_SPECULAR...) Param[1]: material (type: Material *) Param[2]: mapType (type: int) Param[3]: texture (type: Texture2D) -Function 517: SetModelMeshMaterial() (3 input parameters) +Function 519: SetModelMeshMaterial() (3 input parameters) Name: SetModelMeshMaterial Return type: void Description: Set material for a mesh Param[1]: model (type: Model *) Param[2]: meshId (type: int) Param[3]: materialId (type: int) -Function 518: LoadModelAnimations() (2 input parameters) +Function 520: LoadModelAnimations() (2 input parameters) Name: LoadModelAnimations Return type: ModelAnimation * Description: Load model animations from file Param[1]: fileName (type: const char *) Param[2]: animCount (type: int *) -Function 519: UpdateModelAnimation() (3 input parameters) +Function 521: UpdateModelAnimation() (3 input parameters) Name: UpdateModelAnimation Return type: void Description: Update model animation pose (CPU) Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) Param[3]: frame (type: int) -Function 520: UpdateModelAnimationBones() (3 input parameters) +Function 522: UpdateModelAnimationBones() (3 input parameters) Name: UpdateModelAnimationBones Return type: void Description: Update model animation mesh bone matrices (GPU skinning) Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) Param[3]: frame (type: int) -Function 521: UnloadModelAnimation() (1 input parameters) +Function 523: UnloadModelAnimation() (1 input parameters) Name: UnloadModelAnimation Return type: void Description: Unload animation data Param[1]: anim (type: ModelAnimation) -Function 522: UnloadModelAnimations() (2 input parameters) +Function 524: UnloadModelAnimations() (2 input parameters) Name: UnloadModelAnimations Return type: void Description: Unload animation array data Param[1]: animations (type: ModelAnimation *) Param[2]: animCount (type: int) -Function 523: IsModelAnimationValid() (2 input parameters) +Function 525: IsModelAnimationValid() (2 input parameters) Name: IsModelAnimationValid Return type: bool Description: Check model animation skeleton match Param[1]: model (type: Model) Param[2]: anim (type: ModelAnimation) -Function 524: CheckCollisionSpheres() (4 input parameters) +Function 526: CheckCollisionSpheres() (4 input parameters) Name: CheckCollisionSpheres Return type: bool Description: Check collision between two spheres @@ -4368,40 +4379,40 @@ Function 524: CheckCollisionSpheres() (4 input parameters) Param[2]: radius1 (type: float) Param[3]: center2 (type: Vector3) Param[4]: radius2 (type: float) -Function 525: CheckCollisionBoxes() (2 input parameters) +Function 527: CheckCollisionBoxes() (2 input parameters) Name: CheckCollisionBoxes Return type: bool Description: Check collision between two bounding boxes Param[1]: box1 (type: BoundingBox) Param[2]: box2 (type: BoundingBox) -Function 526: CheckCollisionBoxSphere() (3 input parameters) +Function 528: CheckCollisionBoxSphere() (3 input parameters) Name: CheckCollisionBoxSphere Return type: bool Description: Check collision between box and sphere Param[1]: box (type: BoundingBox) Param[2]: center (type: Vector3) Param[3]: radius (type: float) -Function 527: GetRayCollisionSphere() (3 input parameters) +Function 529: GetRayCollisionSphere() (3 input parameters) Name: GetRayCollisionSphere Return type: RayCollision Description: Get collision info between ray and sphere Param[1]: ray (type: Ray) Param[2]: center (type: Vector3) Param[3]: radius (type: float) -Function 528: GetRayCollisionBox() (2 input parameters) +Function 530: GetRayCollisionBox() (2 input parameters) Name: GetRayCollisionBox Return type: RayCollision Description: Get collision info between ray and box Param[1]: ray (type: Ray) Param[2]: box (type: BoundingBox) -Function 529: GetRayCollisionMesh() (3 input parameters) +Function 531: GetRayCollisionMesh() (3 input parameters) Name: GetRayCollisionMesh Return type: RayCollision Description: Get collision info between ray and mesh Param[1]: ray (type: Ray) Param[2]: mesh (type: Mesh) Param[3]: transform (type: Matrix) -Function 530: GetRayCollisionTriangle() (4 input parameters) +Function 532: GetRayCollisionTriangle() (4 input parameters) Name: GetRayCollisionTriangle Return type: RayCollision Description: Get collision info between ray and triangle @@ -4409,7 +4420,7 @@ Function 530: GetRayCollisionTriangle() (4 input parameters) Param[2]: p1 (type: Vector3) Param[3]: p2 (type: Vector3) Param[4]: p3 (type: Vector3) -Function 531: GetRayCollisionQuad() (5 input parameters) +Function 533: GetRayCollisionQuad() (5 input parameters) Name: GetRayCollisionQuad Return type: RayCollision Description: Get collision info between ray and quad @@ -4418,158 +4429,158 @@ Function 531: GetRayCollisionQuad() (5 input parameters) Param[3]: p2 (type: Vector3) Param[4]: p3 (type: Vector3) Param[5]: p4 (type: Vector3) -Function 532: InitAudioDevice() (0 input parameters) +Function 534: InitAudioDevice() (0 input parameters) Name: InitAudioDevice Return type: void Description: Initialize audio device and context No input parameters -Function 533: CloseAudioDevice() (0 input parameters) +Function 535: CloseAudioDevice() (0 input parameters) Name: CloseAudioDevice Return type: void Description: Close the audio device and context No input parameters -Function 534: IsAudioDeviceReady() (0 input parameters) +Function 536: IsAudioDeviceReady() (0 input parameters) Name: IsAudioDeviceReady Return type: bool Description: Check if audio device has been initialized successfully No input parameters -Function 535: SetMasterVolume() (1 input parameters) +Function 537: SetMasterVolume() (1 input parameters) Name: SetMasterVolume Return type: void Description: Set master volume (listener) Param[1]: volume (type: float) -Function 536: GetMasterVolume() (0 input parameters) +Function 538: GetMasterVolume() (0 input parameters) Name: GetMasterVolume Return type: float Description: Get master volume (listener) No input parameters -Function 537: LoadWave() (1 input parameters) +Function 539: LoadWave() (1 input parameters) Name: LoadWave Return type: Wave Description: Load wave data from file Param[1]: fileName (type: const char *) -Function 538: LoadWaveFromMemory() (3 input parameters) +Function 540: LoadWaveFromMemory() (3 input parameters) Name: LoadWaveFromMemory Return type: Wave Description: Load wave from memory buffer, fileType refers to extension: i.e. '.wav' Param[1]: fileType (type: const char *) Param[2]: fileData (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 539: IsWaveValid() (1 input parameters) +Function 541: IsWaveValid() (1 input parameters) Name: IsWaveValid Return type: bool Description: Checks if wave data is valid (data loaded and parameters) Param[1]: wave (type: Wave) -Function 540: LoadSound() (1 input parameters) +Function 542: LoadSound() (1 input parameters) Name: LoadSound Return type: Sound Description: Load sound from file Param[1]: fileName (type: const char *) -Function 541: LoadSoundFromWave() (1 input parameters) +Function 543: LoadSoundFromWave() (1 input parameters) Name: LoadSoundFromWave Return type: Sound Description: Load sound from wave data Param[1]: wave (type: Wave) -Function 542: LoadSoundAlias() (1 input parameters) +Function 544: LoadSoundAlias() (1 input parameters) Name: LoadSoundAlias Return type: Sound Description: Create a new sound that shares the same sample data as the source sound, does not own the sound data Param[1]: source (type: Sound) -Function 543: IsSoundValid() (1 input parameters) +Function 545: IsSoundValid() (1 input parameters) Name: IsSoundValid Return type: bool Description: Checks if a sound is valid (data loaded and buffers initialized) Param[1]: sound (type: Sound) -Function 544: UpdateSound() (3 input parameters) +Function 546: UpdateSound() (3 input parameters) Name: UpdateSound Return type: void Description: Update sound buffer with new data (default data format: 32 bit float, stereo) Param[1]: sound (type: Sound) Param[2]: data (type: const void *) Param[3]: sampleCount (type: int) -Function 545: UnloadWave() (1 input parameters) +Function 547: UnloadWave() (1 input parameters) Name: UnloadWave Return type: void Description: Unload wave data Param[1]: wave (type: Wave) -Function 546: UnloadSound() (1 input parameters) +Function 548: UnloadSound() (1 input parameters) Name: UnloadSound Return type: void Description: Unload sound Param[1]: sound (type: Sound) -Function 547: UnloadSoundAlias() (1 input parameters) +Function 549: UnloadSoundAlias() (1 input parameters) Name: UnloadSoundAlias Return type: void Description: Unload a sound alias (does not deallocate sample data) Param[1]: alias (type: Sound) -Function 548: ExportWave() (2 input parameters) +Function 550: ExportWave() (2 input parameters) Name: ExportWave Return type: bool Description: Export wave data to file, returns true on success Param[1]: wave (type: Wave) Param[2]: fileName (type: const char *) -Function 549: ExportWaveAsCode() (2 input parameters) +Function 551: ExportWaveAsCode() (2 input parameters) Name: ExportWaveAsCode Return type: bool Description: Export wave sample data to code (.h), returns true on success Param[1]: wave (type: Wave) Param[2]: fileName (type: const char *) -Function 550: PlaySound() (1 input parameters) +Function 552: PlaySound() (1 input parameters) Name: PlaySound Return type: void Description: Play a sound Param[1]: sound (type: Sound) -Function 551: StopSound() (1 input parameters) +Function 553: StopSound() (1 input parameters) Name: StopSound Return type: void Description: Stop playing a sound Param[1]: sound (type: Sound) -Function 552: PauseSound() (1 input parameters) +Function 554: PauseSound() (1 input parameters) Name: PauseSound Return type: void Description: Pause a sound Param[1]: sound (type: Sound) -Function 553: ResumeSound() (1 input parameters) +Function 555: ResumeSound() (1 input parameters) Name: ResumeSound Return type: void Description: Resume a paused sound Param[1]: sound (type: Sound) -Function 554: IsSoundPlaying() (1 input parameters) +Function 556: IsSoundPlaying() (1 input parameters) Name: IsSoundPlaying Return type: bool Description: Check if a sound is currently playing Param[1]: sound (type: Sound) -Function 555: SetSoundVolume() (2 input parameters) +Function 557: SetSoundVolume() (2 input parameters) Name: SetSoundVolume Return type: void Description: Set volume for a sound (1.0 is max level) Param[1]: sound (type: Sound) Param[2]: volume (type: float) -Function 556: SetSoundPitch() (2 input parameters) +Function 558: SetSoundPitch() (2 input parameters) Name: SetSoundPitch Return type: void Description: Set pitch for a sound (1.0 is base level) Param[1]: sound (type: Sound) Param[2]: pitch (type: float) -Function 557: SetSoundPan() (2 input parameters) +Function 559: SetSoundPan() (2 input parameters) Name: SetSoundPan Return type: void Description: Set pan for a sound (-1.0 left, 0.0 center, 1.0 right) Param[1]: sound (type: Sound) Param[2]: pan (type: float) -Function 558: WaveCopy() (1 input parameters) +Function 560: WaveCopy() (1 input parameters) Name: WaveCopy Return type: Wave Description: Copy a wave to a new wave Param[1]: wave (type: Wave) -Function 559: WaveCrop() (3 input parameters) +Function 561: WaveCrop() (3 input parameters) Name: WaveCrop Return type: void Description: Crop a wave to defined frames range Param[1]: wave (type: Wave *) Param[2]: initFrame (type: int) Param[3]: finalFrame (type: int) -Function 560: WaveFormat() (4 input parameters) +Function 562: WaveFormat() (4 input parameters) Name: WaveFormat Return type: void Description: Convert wave data to desired format @@ -4577,203 +4588,203 @@ Function 560: WaveFormat() (4 input parameters) Param[2]: sampleRate (type: int) Param[3]: sampleSize (type: int) Param[4]: channels (type: int) -Function 561: LoadWaveSamples() (1 input parameters) +Function 563: LoadWaveSamples() (1 input parameters) Name: LoadWaveSamples Return type: float * Description: Load samples data from wave as a 32bit float data array Param[1]: wave (type: Wave) -Function 562: UnloadWaveSamples() (1 input parameters) +Function 564: UnloadWaveSamples() (1 input parameters) Name: UnloadWaveSamples Return type: void Description: Unload samples data loaded with LoadWaveSamples() Param[1]: samples (type: float *) -Function 563: LoadMusicStream() (1 input parameters) +Function 565: LoadMusicStream() (1 input parameters) Name: LoadMusicStream Return type: Music Description: Load music stream from file Param[1]: fileName (type: const char *) -Function 564: LoadMusicStreamFromMemory() (3 input parameters) +Function 566: LoadMusicStreamFromMemory() (3 input parameters) Name: LoadMusicStreamFromMemory Return type: Music Description: Load music stream from data Param[1]: fileType (type: const char *) Param[2]: data (type: const unsigned char *) Param[3]: dataSize (type: int) -Function 565: IsMusicValid() (1 input parameters) +Function 567: IsMusicValid() (1 input parameters) Name: IsMusicValid Return type: bool Description: Checks if a music stream is valid (context and buffers initialized) Param[1]: music (type: Music) -Function 566: UnloadMusicStream() (1 input parameters) +Function 568: UnloadMusicStream() (1 input parameters) Name: UnloadMusicStream Return type: void Description: Unload music stream Param[1]: music (type: Music) -Function 567: PlayMusicStream() (1 input parameters) +Function 569: PlayMusicStream() (1 input parameters) Name: PlayMusicStream Return type: void Description: Start music playing Param[1]: music (type: Music) -Function 568: IsMusicStreamPlaying() (1 input parameters) +Function 570: IsMusicStreamPlaying() (1 input parameters) Name: IsMusicStreamPlaying Return type: bool Description: Check if music is playing Param[1]: music (type: Music) -Function 569: UpdateMusicStream() (1 input parameters) +Function 571: UpdateMusicStream() (1 input parameters) Name: UpdateMusicStream Return type: void Description: Updates buffers for music streaming Param[1]: music (type: Music) -Function 570: StopMusicStream() (1 input parameters) +Function 572: StopMusicStream() (1 input parameters) Name: StopMusicStream Return type: void Description: Stop music playing Param[1]: music (type: Music) -Function 571: PauseMusicStream() (1 input parameters) +Function 573: PauseMusicStream() (1 input parameters) Name: PauseMusicStream Return type: void Description: Pause music playing Param[1]: music (type: Music) -Function 572: ResumeMusicStream() (1 input parameters) +Function 574: ResumeMusicStream() (1 input parameters) Name: ResumeMusicStream Return type: void Description: Resume playing paused music Param[1]: music (type: Music) -Function 573: SeekMusicStream() (2 input parameters) +Function 575: SeekMusicStream() (2 input parameters) Name: SeekMusicStream Return type: void Description: Seek music to a position (in seconds) Param[1]: music (type: Music) Param[2]: position (type: float) -Function 574: SetMusicVolume() (2 input parameters) +Function 576: SetMusicVolume() (2 input parameters) Name: SetMusicVolume Return type: void Description: Set volume for music (1.0 is max level) Param[1]: music (type: Music) Param[2]: volume (type: float) -Function 575: SetMusicPitch() (2 input parameters) +Function 577: SetMusicPitch() (2 input parameters) Name: SetMusicPitch Return type: void Description: Set pitch for a music (1.0 is base level) Param[1]: music (type: Music) Param[2]: pitch (type: float) -Function 576: SetMusicPan() (2 input parameters) +Function 578: SetMusicPan() (2 input parameters) Name: SetMusicPan Return type: void Description: Set pan for a music (-1.0 left, 0.0 center, 1.0 right) Param[1]: music (type: Music) Param[2]: pan (type: float) -Function 577: GetMusicTimeLength() (1 input parameters) +Function 579: GetMusicTimeLength() (1 input parameters) Name: GetMusicTimeLength Return type: float Description: Get music time length (in seconds) Param[1]: music (type: Music) -Function 578: GetMusicTimePlayed() (1 input parameters) +Function 580: GetMusicTimePlayed() (1 input parameters) Name: GetMusicTimePlayed Return type: float Description: Get current music time played (in seconds) Param[1]: music (type: Music) -Function 579: LoadAudioStream() (3 input parameters) +Function 581: LoadAudioStream() (3 input parameters) Name: LoadAudioStream Return type: AudioStream Description: Load audio stream (to stream raw audio pcm data) Param[1]: sampleRate (type: unsigned int) Param[2]: sampleSize (type: unsigned int) Param[3]: channels (type: unsigned int) -Function 580: IsAudioStreamValid() (1 input parameters) +Function 582: IsAudioStreamValid() (1 input parameters) Name: IsAudioStreamValid Return type: bool Description: Checks if an audio stream is valid (buffers initialized) Param[1]: stream (type: AudioStream) -Function 581: UnloadAudioStream() (1 input parameters) +Function 583: UnloadAudioStream() (1 input parameters) Name: UnloadAudioStream Return type: void Description: Unload audio stream and free memory Param[1]: stream (type: AudioStream) -Function 582: UpdateAudioStream() (3 input parameters) +Function 584: UpdateAudioStream() (3 input parameters) Name: UpdateAudioStream Return type: void Description: Update audio stream buffers with data Param[1]: stream (type: AudioStream) Param[2]: data (type: const void *) Param[3]: frameCount (type: int) -Function 583: IsAudioStreamProcessed() (1 input parameters) +Function 585: IsAudioStreamProcessed() (1 input parameters) Name: IsAudioStreamProcessed Return type: bool Description: Check if any audio stream buffers requires refill Param[1]: stream (type: AudioStream) -Function 584: PlayAudioStream() (1 input parameters) +Function 586: PlayAudioStream() (1 input parameters) Name: PlayAudioStream Return type: void Description: Play audio stream Param[1]: stream (type: AudioStream) -Function 585: PauseAudioStream() (1 input parameters) +Function 587: PauseAudioStream() (1 input parameters) Name: PauseAudioStream Return type: void Description: Pause audio stream Param[1]: stream (type: AudioStream) -Function 586: ResumeAudioStream() (1 input parameters) +Function 588: ResumeAudioStream() (1 input parameters) Name: ResumeAudioStream Return type: void Description: Resume audio stream Param[1]: stream (type: AudioStream) -Function 587: IsAudioStreamPlaying() (1 input parameters) +Function 589: IsAudioStreamPlaying() (1 input parameters) Name: IsAudioStreamPlaying Return type: bool Description: Check if audio stream is playing Param[1]: stream (type: AudioStream) -Function 588: StopAudioStream() (1 input parameters) +Function 590: StopAudioStream() (1 input parameters) Name: StopAudioStream Return type: void Description: Stop audio stream Param[1]: stream (type: AudioStream) -Function 589: SetAudioStreamVolume() (2 input parameters) +Function 591: SetAudioStreamVolume() (2 input parameters) Name: SetAudioStreamVolume Return type: void Description: Set volume for audio stream (1.0 is max level) Param[1]: stream (type: AudioStream) Param[2]: volume (type: float) -Function 590: SetAudioStreamPitch() (2 input parameters) +Function 592: SetAudioStreamPitch() (2 input parameters) Name: SetAudioStreamPitch Return type: void Description: Set pitch for audio stream (1.0 is base level) Param[1]: stream (type: AudioStream) Param[2]: pitch (type: float) -Function 591: SetAudioStreamPan() (2 input parameters) +Function 593: SetAudioStreamPan() (2 input parameters) Name: SetAudioStreamPan Return type: void Description: Set pan for audio stream (0.5 is centered) Param[1]: stream (type: AudioStream) Param[2]: pan (type: float) -Function 592: SetAudioStreamBufferSizeDefault() (1 input parameters) +Function 594: SetAudioStreamBufferSizeDefault() (1 input parameters) Name: SetAudioStreamBufferSizeDefault Return type: void Description: Default size for new audio streams Param[1]: size (type: int) -Function 593: SetAudioStreamCallback() (2 input parameters) +Function 595: SetAudioStreamCallback() (2 input parameters) Name: SetAudioStreamCallback Return type: void Description: Audio thread callback to request new data Param[1]: stream (type: AudioStream) Param[2]: callback (type: AudioCallback) -Function 594: AttachAudioStreamProcessor() (2 input parameters) +Function 596: AttachAudioStreamProcessor() (2 input parameters) Name: AttachAudioStreamProcessor Return type: void Description: Attach audio stream processor to stream, receives frames x 2 samples as 'float' (stereo) Param[1]: stream (type: AudioStream) Param[2]: processor (type: AudioCallback) -Function 595: DetachAudioStreamProcessor() (2 input parameters) +Function 597: DetachAudioStreamProcessor() (2 input parameters) Name: DetachAudioStreamProcessor Return type: void Description: Detach audio stream processor from stream Param[1]: stream (type: AudioStream) Param[2]: processor (type: AudioCallback) -Function 596: AttachAudioMixedProcessor() (1 input parameters) +Function 598: AttachAudioMixedProcessor() (1 input parameters) Name: AttachAudioMixedProcessor Return type: void Description: Attach audio stream processor to the entire audio pipeline, receives frames x 2 samples as 'float' (stereo) Param[1]: processor (type: AudioCallback) -Function 597: DetachAudioMixedProcessor() (1 input parameters) +Function 599: DetachAudioMixedProcessor() (1 input parameters) Name: DetachAudioMixedProcessor Return type: void Description: Detach audio stream processor from the entire audio pipeline diff --git a/tools/rlparser/output/raylib_api.xml b/tools/rlparser/output/raylib_api.xml index 3853ac74f..c1f9bc818 100644 --- a/tools/rlparser/output/raylib_api.xml +++ b/tools/rlparser/output/raylib_api.xml @@ -280,8 +280,7 @@ - - + @@ -679,7 +678,7 @@ - + @@ -1137,6 +1136,14 @@ + + + + + + + + diff --git a/tools/rlparser/rlparser.c b/tools/rlparser/rlparser.c index c291c3038..899ba7db6 100644 --- a/tools/rlparser/rlparser.c +++ b/tools/rlparser/rlparser.c @@ -198,7 +198,7 @@ static void ExportParsedData(const char *fileName, int format); // Export parsed //---------------------------------------------------------------------------------- // Program main entry point //---------------------------------------------------------------------------------- -int main(int argc, char* argv[]) +int main(int argc, char *argv[]) { if (argc > 1) ProcessCommandLine(argc, argv);