diff --git a/examples/Makefile b/examples/Makefile index 25baa9bbe..afd9533c9 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -504,10 +504,10 @@ CORE = \ core/core_2d_camera_platformer \ core/core_2d_camera_split_screen \ core/core_3d_camera_first_person \ + core/core_3d_camera_fps \ core/core_3d_camera_free \ core/core_3d_camera_mode \ core/core_3d_camera_split_screen \ - core/core_3d_camera_fps \ core/core_3d_picking \ core/core_automation_events \ core/core_basic_screen_manager \ diff --git a/examples/Makefile.Web b/examples/Makefile.Web index 74b94dd6f..be93ca36a 100644 --- a/examples/Makefile.Web +++ b/examples/Makefile.Web @@ -504,10 +504,10 @@ CORE = \ core/core_2d_camera_platformer \ core/core_2d_camera_split_screen \ core/core_3d_camera_first_person \ + core/core_3d_camera_fps \ core/core_3d_camera_free \ core/core_3d_camera_mode \ core/core_3d_camera_split_screen \ - core/core_3d_camera_fps \ core/core_3d_picking \ core/core_automation_events \ core/core_basic_screen_manager \ @@ -695,6 +695,9 @@ core/core_2d_camera_split_screen: core/core_2d_camera_split_screen.c core/core_3d_camera_first_person: core/core_3d_camera_first_person.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) +core/core_3d_camera_fps: core/core_3d_camera_fps.c + $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) + core/core_3d_camera_free: core/core_3d_camera_free.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) @@ -704,9 +707,6 @@ core/core_3d_camera_mode: core/core_3d_camera_mode.c core/core_3d_camera_split_screen: core/core_3d_camera_split_screen.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) -core/core_3d_camera_fps: core/core_3d_camera_fps.c - $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) - core/core_3d_picking: core/core_3d_picking.c $(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM) diff --git a/examples/audio/audio_sound_positioning.c b/examples/audio/audio_sound_positioning.c index 5bef2d671..9f09420a2 100644 --- a/examples/audio/audio_sound_positioning.c +++ b/examples/audio/audio_sound_positioning.c @@ -19,7 +19,9 @@ #include "raymath.h" -// Sound positioning function +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ static void SetSoundPosition(Camera listener, Sound sound, Vector3 position, float maxDist); //------------------------------------------------------------------------------------ @@ -94,7 +96,10 @@ int main(void) //-------------------------------------------------------------------------------------- } -// Sound positioning function +//------------------------------------------------------------------------------------ +// Module Functions Definition +//------------------------------------------------------------------------------------ +// Set sound 3d position static void SetSoundPosition(Camera listener, Sound sound, Vector3 position, float maxDist) { // Calculate direction vector and distance between listener and sound source diff --git a/examples/audio/audio_stream_effects.c b/examples/audio/audio_stream_effects.c index b848c8c31..0d06e1e03 100644 --- a/examples/audio/audio_stream_effects.c +++ b/examples/audio/audio_stream_effects.c @@ -17,7 +17,9 @@ #include // Required for: NULL -// Required delay effect variables +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- static float *delayBuffer = NULL; static unsigned int delayBufferSize = 0; static unsigned int delayReadIndex = 2; diff --git a/examples/core/core_2d_camera_platformer.c b/examples/core/core_2d_camera_platformer.c index 9a6ec9ade..45bad4015 100644 --- a/examples/core/core_2d_camera_platformer.c +++ b/examples/core/core_2d_camera_platformer.c @@ -22,6 +22,9 @@ #define PLAYER_JUMP_SPD 350.0f #define PLAYER_HOR_SPD 200.0f +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- typedef struct Player { Vector2 position; float speed; @@ -35,7 +38,7 @@ typedef struct EnvItem { } EnvItem; //---------------------------------------------------------------------------------- -// Module functions declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- void UpdatePlayer(Player *player, EnvItem *envItems, int envItemsLength, float delta); void UpdateCameraCenter(Camera2D *camera, Player *player, EnvItem *envItems, int envItemsLength, float delta, int width, int height); diff --git a/examples/core/core_3d_camera_fps.c b/examples/core/core_3d_camera_fps.c index a3f1d5716..980660b30 100644 --- a/examples/core/core_3d_camera_fps.c +++ b/examples/core/core_3d_camera_fps.c @@ -18,7 +18,6 @@ #include "raylib.h" #include "raymath.h" -#include "rcamera.h" //---------------------------------------------------------------------------------- // Defines and Macros @@ -65,10 +64,10 @@ static float headLerp = STAND_HEIGHT; static Vector2 lean = { 0 }; //---------------------------------------------------------------------------------- -// Module functions declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- static void DrawLevel(void); -static void UpdateCameraAngle(Camera *camera); +static void UpdateCameraFPS(Camera *camera); static void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold); //------------------------------------------------------------------------------------ @@ -84,7 +83,7 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d first-person camera controller"); // Initialize camera variables - // NOTE: UpdateCameraAngle() takes care of the rest + // NOTE: UpdateCameraFPS() takes care of the rest Camera camera = { 0 }; camera.fovy = 60.0f; camera.projection = CAMERA_PERSPECTIVE; @@ -94,7 +93,7 @@ int main(void) player.position.z, }; - UpdateCameraAngle(&camera); // Update camera parameters + UpdateCameraFPS(&camera); // Update camera parameters DisableCursor(); // Limit cursor to relative movement inside the window @@ -138,7 +137,7 @@ int main(void) lean.x = Lerp(lean.x, sideway*0.02f, 10.0f*delta); lean.y = Lerp(lean.y, forward*0.015f, 10.0f*delta); - UpdateCameraAngle(&camera); + UpdateCameraFPS(&camera); //---------------------------------------------------------------------------------- // Draw @@ -173,9 +172,10 @@ int main(void) } //---------------------------------------------------------------------------------- -// Module functions definition +// Module Functions Definition //---------------------------------------------------------------------------------- -void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed, bool crouchHold) +// Update body considering current world state +void UpdateBody(Body *body, float rot, char side, char forward, bool jumpPressed, bool crouchHold) { Vector2 input = (Vector2){ (float)side, (float)-forward }; @@ -237,8 +237,8 @@ void UpdateBody(Body* body, float rot, char side, char forward, bool jumpPressed } } -// Update camera -static void UpdateCameraAngle(Camera *camera) +// Update camera for FPS behaviour +static void UpdateCameraFPS(Camera *camera) { const Vector3 up = (Vector3){ 0.0f, 1.0f, 0.0f }; const Vector3 targetOffset = (Vector3){ 0.0f, 0.0f, -1.0f }; diff --git a/examples/core/core_basic_window_web.c b/examples/core/core_basic_window_web.c index c4aa18177..7877337a3 100644 --- a/examples/core/core_basic_window_web.c +++ b/examples/core/core_basic_window_web.c @@ -32,7 +32,7 @@ const int screenWidth = 800; const int screenHeight = 450; //---------------------------------------------------------------------------------- -// Module functions declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- void UpdateDrawFrame(void); // Update and Draw one frame diff --git a/examples/core/core_high_dpi.c b/examples/core/core_high_dpi.c index 8de5fa261..636442401 100644 --- a/examples/core/core_high_dpi.c +++ b/examples/core/core_high_dpi.c @@ -14,7 +14,7 @@ #include "raylib.h" //------------------------------------------------------------------------------------ -// Module functions declaration +// Module Functions Declaration //------------------------------------------------------------------------------------ static void DrawTextCenter(const char *text, int x, int y, int fontSize, Color color); @@ -120,7 +120,7 @@ int main(void) } //------------------------------------------------------------------------------------ -// Module functions definition +// Module Functions Definition //------------------------------------------------------------------------------------ static void DrawTextCenter(const char *text, int x, int y, int fontSize, Color color) { diff --git a/examples/core/core_loading_thread.c b/examples/core/core_loading_thread.c index 1fa84640d..3d04f94a7 100644 --- a/examples/core/core_loading_thread.c +++ b/examples/core/core_loading_thread.c @@ -20,16 +20,18 @@ // WARNING: This example does not build on Windows with MSVC compiler #include "pthread.h" // POSIX style threads management -#include // C11 atomic data types - +#include // Required for: C11 atomic data types #include // Required for: clock() // Using C11 atomics for synchronization // NOTE: A plain bool (or any plain data type for that matter) can't be used for inter-thread synchronization -static atomic_bool dataLoaded = false; // Data Loaded completion indicator -static void *LoadDataThread(void *arg); // Loading data thread function declaration +static atomic_bool dataLoaded = false; // Data Loaded completion indicator +static atomic_int dataProgress = 0; // Data progress accumulator -static atomic_int dataProgress = 0; // Data progress accumulator +//------------------------------------------------------------------------------------ +// Module Functions Declaration +//------------------------------------------------------------------------------------ +static void *LoadDataThread(void *arg); // Loading data thread function declaration //------------------------------------------------------------------------------------ // Program main entry point @@ -134,6 +136,9 @@ int main(void) return 0; } +//------------------------------------------------------------------------------------ +// Module Functions Definition +//------------------------------------------------------------------------------------ // Loading data thread function definition static void *LoadDataThread(void *arg) { diff --git a/examples/core/core_random_sequence.c b/examples/core/core_random_sequence.c index be63e2f9b..67990df32 100644 --- a/examples/core/core_random_sequence.c +++ b/examples/core/core_random_sequence.c @@ -18,20 +18,22 @@ #include "raylib.h" #include "raymath.h" -#include // Required for: malloc() and free() +#include // Required for: malloc(), free() +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- typedef struct ColorRect { - Color c; - Rectangle r; + Color color; + Rectangle rect; } ColorRect; //------------------------------------------------------------------------------------ -// Module functions declaration +// Module Functions Declaration //------------------------------------------------------------------------------------ static Color GenerateRandomColor(); static ColorRect *GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight); static void ShuffleColorRectSequence(ColorRect *rectangles, int rectCount); -static void DrawTextCenterKeyHelp(const char *key, const char *text, int posX, int posY, int fontSize, Color color); //------------------------------------------------------------------------------------ // Program main entry point @@ -63,7 +65,9 @@ int main(void) { rectCount++; rectSize = (float)screenWidth/rectCount; - free(rectangles); + RL_FREE(rectangles); + + // Re-generate random sequence with new count rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f*screenHeight); } @@ -73,7 +77,9 @@ int main(void) { rectCount--; rectSize = (float)screenWidth/rectCount; - free(rectangles); + RL_FREE(rectangles); + + // Re-generate random sequence with new count rectangles = GenerateRandomColorRectSequence((float)rectCount, rectSize, (float)screenWidth, 0.75f*screenHeight); } } @@ -85,20 +91,20 @@ int main(void) ClearBackground(RAYWHITE); - int fontSize = 20; for (int i = 0; i < rectCount; i++) { - DrawRectangleRec(rectangles[i].r, rectangles[i].c); - DrawTextCenterKeyHelp("SPACE", "to shuffle the sequence.", 10, screenHeight - 96, fontSize, BLACK); - DrawTextCenterKeyHelp("UP", "to add a rectangle and generate a new sequence.", 10, screenHeight - 64, fontSize, BLACK); - DrawTextCenterKeyHelp("DOWN", "to remove a rectangle and generate a new sequence.", 10, screenHeight - 32, fontSize, BLACK); + DrawRectangleRec(rectangles[i].rect, rectangles[i].color); + + DrawText("Press SPACE to shuffle the sequence", 10, screenHeight - 96, 20, BLACK); + + DrawText("Press SPACE to shuffle the current sequence", 10, screenHeight - 96, 20, BLACK); + DrawText("Press UP to add a rectangle and generate a new sequence", 10, screenHeight - 64, 20, BLACK); + DrawText("Press DOWN to remove a rectangle and generate a new sequence", 10, screenHeight - 32, 20, BLACK); } - const char *rectCountText = TextFormat("%d rectangles", rectCount); - int rectCountTextSize = MeasureText(rectCountText, fontSize); - DrawText(rectCountText, screenWidth - rectCountTextSize - 10, 10, fontSize, BLACK); + DrawText(TextFormat("Count: %d rectangles", rectCount), 10, 10, 20, MAROON); - DrawFPS(10, 10); + DrawFPS(screenWidth - 80, 10); EndDrawing(); //---------------------------------------------------------------------------------- @@ -114,7 +120,7 @@ int main(void) } //------------------------------------------------------------------------------------ -// Module functions definition +// Module Functions Definition //------------------------------------------------------------------------------------ static Color GenerateRandomColor() { @@ -130,7 +136,8 @@ static Color GenerateRandomColor() static ColorRect *GenerateRandomColorRectSequence(float rectCount, float rectWidth, float screenWidth, float screenHeight) { - ColorRect *rectangles = (ColorRect *)malloc((int)rectCount*sizeof(ColorRect)); + ColorRect *rectangles = (ColorRect *)RL_CALLOC((int)rectCount, sizeof(ColorRect)); + int *seq = LoadRandomSequence((unsigned int)rectCount, 0, (unsigned int)rectCount - 1); float rectSeqWidth = rectCount*rectWidth; float startX = (screenWidth - rectSeqWidth)*0.5f; @@ -139,8 +146,8 @@ static ColorRect *GenerateRandomColorRectSequence(float rectCount, float rectWid { int rectHeight = (int)Remap((float)seq[i], 0, rectCount - 1, 0, screenHeight); - rectangles[i].c = GenerateRandomColor(); - rectangles[i].r = CLITERAL(Rectangle){ startX + i*rectWidth, screenHeight - rectHeight, rectWidth, (float)rectHeight }; + rectangles[i].color = GenerateRandomColor(); + rectangles[i].rect = CLITERAL(Rectangle){ startX + i*rectWidth, screenHeight - rectHeight, rectWidth, (float)rectHeight }; } UnloadRandomSequence(seq); @@ -159,28 +166,13 @@ static void ShuffleColorRectSequence(ColorRect *rectangles, int rectCount) // Swap only the color and height ColorRect tmp = *r1; - r1->c = r2->c; - r1->r.height = r2->r.height; - r1->r.y = r2->r.y; - r2->c = tmp.c; - r2->r.height = tmp.r.height; - r2->r.y = tmp.r.y; + r1->color = r2->color; + r1->rect.height = r2->rect.height; + r1->rect.y = r2->rect.y; + r2->color = tmp.color; + r2->rect.height = tmp.rect.height; + r2->rect.y = tmp.rect.y; } UnloadRandomSequence(seq); } - -static void DrawTextCenterKeyHelp(const char *key, const char *text, int posX, int posY, int fontSize, Color color) -{ - int spaceSize = MeasureText(" ", fontSize); - int pressSize = MeasureText("Press", fontSize); - int keySize = MeasureText(key, fontSize); - int textSizeCurrent = 0; - - DrawText("Press", posX, posY, fontSize, color); - textSizeCurrent += pressSize + 2*spaceSize; - DrawText(key, posX + textSizeCurrent, posY, fontSize, RED); - DrawRectangle(posX + textSizeCurrent, posY + fontSize, keySize, 3, RED); - textSizeCurrent += keySize + 2*spaceSize; - DrawText(text, posX + textSizeCurrent, posY, fontSize, color); -} diff --git a/examples/examples_list.txt b/examples/examples_list.txt index a980ff4a4..0a20d8155 100644 --- a/examples/examples_list.txt +++ b/examples/examples_list.txt @@ -100,6 +100,7 @@ text;text_input_box;⭐️⭐️☆☆;1.7;3.5;"Ramon Santamaria";@raysan5 text;text_writing_anim;⭐️⭐️☆☆;1.4;1.4;"Ramon Santamaria";@raysan5 text;text_rectangle_bounds;⭐️⭐️⭐️⭐️;2.5;4.0;"Vlad Adrian";@demizdor text;text_unicode;⭐️⭐️⭐️⭐️;2.5;4.0;"Vlad Adrian";@demizdor +text;text_unicode_ranges;⭐️⭐️⭐️⭐️;5.5;5.6;"Vlad Adrian";@demizdor text;text_draw_3d;⭐️⭐️⭐️⭐️;3.5;4.0;"Vlad Adrian";@demizdor text;text_codepoints_loading;⭐️⭐️⭐️☆;4.2;4.2;"Ramon Santamaria";@raysan5 models;models_animation;⭐️⭐️☆☆;2.5;3.5;"Culacant";@culacant @@ -168,4 +169,3 @@ others;easings_testbed;⭐️⭐️⭐️☆;2.5;3.0;"Juan Miguel López";@flash others;raylib_opengl_interop;⭐️⭐️⭐️⭐️;3.8;4.0;"Stephan Soller";@arkanis others;embedded_files_loading;⭐️⭐️☆☆;3.0;3.5;"Kristian Holmgren";@defutura others;raymath_vector_angle;⭐️⭐️☆☆;1.0;4.6;"Ramon Santamaria";@raysan5 -text;text_unicode_ranges;⭐⭐⭐⭐️;2.5;4.0;"Vlad Adrian";@demizdor diff --git a/examples/models/models_rlgl_solar_system.c b/examples/models/models_rlgl_solar_system.c index ad712cb71..2eb041541 100644 --- a/examples/models/models_rlgl_solar_system.c +++ b/examples/models/models_rlgl_solar_system.c @@ -133,9 +133,8 @@ int main(void) } //-------------------------------------------------------------------------------------------- -// Module Functions Definitions (local) +// Module Functions Definition //-------------------------------------------------------------------------------------------- - // Draw sphere without any matrix transformation // NOTE: Sphere is drawn in world position ( 0, 0, 0 ) with radius 1.0f void DrawSphereBasic(Color color) diff --git a/examples/models/rlights.h b/examples/models/rlights.h index e38b0015a..aba907b5f 100644 --- a/examples/models/rlights.h +++ b/examples/models/rlights.h @@ -109,7 +109,7 @@ void UpdateLightValues(Shader shader, Light light); // Send light proper static int lightsCount = 0; // Current amount of created lights //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- // ... diff --git a/examples/others/rlgl_standalone.c b/examples/others/rlgl_standalone.c index eddb63a0f..288f06419 100644 --- a/examples/others/rlgl_standalone.c +++ b/examples/others/rlgl_standalone.c @@ -77,7 +77,7 @@ #define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray //---------------------------------------------------------------------------------- -// Structures Definition +// Types and Structures Definition //---------------------------------------------------------------------------------- // Color, 4 components, R8G8B8A8 (32bit) typedef struct Color { @@ -97,7 +97,7 @@ typedef struct Camera { } Camera; //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- static void ErrorCallback(int error, const char *description); static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); @@ -260,7 +260,7 @@ int main(void) } //---------------------------------------------------------------------------------- -// Module specific Functions Definitions +// Module Functions Definitions //---------------------------------------------------------------------------------- // GLFW3: Error callback diff --git a/examples/shaders/rlights.h b/examples/shaders/rlights.h index e38b0015a..aba907b5f 100644 --- a/examples/shaders/rlights.h +++ b/examples/shaders/rlights.h @@ -109,7 +109,7 @@ void UpdateLightValues(Shader shader, Light light); // Send light proper static int lightsCount = 0; // Current amount of created lights //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- // ... diff --git a/examples/shaders/shaders_basic_pbr.c b/examples/shaders/shaders_basic_pbr.c index 49c03eb31..14ab0d677 100644 --- a/examples/shaders/shaders_basic_pbr.c +++ b/examples/shaders/shaders_basic_pbr.c @@ -34,7 +34,6 @@ //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- - // Light type typedef enum { LIGHT_DIRECTIONAL = 0, @@ -66,7 +65,7 @@ typedef struct { static int lightCount = 0; // Current number of dynamic lights that have been created //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- // Create a light and get shader locations static Light CreateLight(int type, Vector3 position, Vector3 target, Color color, float intensity, Shader shader); @@ -76,7 +75,7 @@ static Light CreateLight(int type, Vector3 position, Vector3 target, Color color static void UpdateLight(Shader shader, Light light); //---------------------------------------------------------------------------------- -// Main Entry Point +// Program main entry point //---------------------------------------------------------------------------------- int main() { @@ -237,9 +236,9 @@ int main() Vector4 floorEmissiveColor = ColorNormalize(floor.materials[0].maps[MATERIAL_MAP_EMISSION].color); SetShaderValue(shader, emissiveColorLoc, &floorEmissiveColor, SHADER_UNIFORM_VEC4); - // Set floor metallic and roughness values - SetShaderValue(shader, metallicValueLoc, &floor.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT); - SetShaderValue(shader, roughnessValueLoc, &floor.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT); + // Set floor metallic and roughness values + SetShaderValue(shader, metallicValueLoc, &floor.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT); + SetShaderValue(shader, roughnessValueLoc, &floor.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT); DrawModel(floor, (Vector3){ 0.0f, 0.0f, 0.0f }, 5.0f, WHITE); // Draw floor model @@ -250,9 +249,9 @@ int main() float emissiveIntensity = 0.01f; SetShaderValue(shader, emissiveIntensityLoc, &emissiveIntensity, SHADER_UNIFORM_FLOAT); - // Set old car metallic and roughness values - SetShaderValue(shader, metallicValueLoc, &car.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT); - SetShaderValue(shader, roughnessValueLoc, &car.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT); + // Set old car metallic and roughness values + SetShaderValue(shader, metallicValueLoc, &car.materials[0].maps[MATERIAL_MAP_METALNESS].value, SHADER_UNIFORM_FLOAT); + SetShaderValue(shader, roughnessValueLoc, &car.materials[0].maps[MATERIAL_MAP_ROUGHNESS].value, SHADER_UNIFORM_FLOAT); DrawModel(car, (Vector3){ 0.0f, 0.0f, 0.0f }, 0.25f, WHITE); // Draw car model @@ -299,6 +298,9 @@ int main() return 0; } +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- // Create light with provided data // NOTE: It updated the global lightCount and it's limited to MAX_LIGHTS static Light CreateLight(int type, Vector3 position, Vector3 target, Color color, float intensity, Shader shader) diff --git a/examples/shaders/shaders_hybrid_render.c b/examples/shaders/shaders_hybrid_render.c index 2ed3d2f79..40a8552f0 100644 --- a/examples/shaders/shaders_hybrid_render.c +++ b/examples/shaders/shaders_hybrid_render.c @@ -16,32 +16,35 @@ ********************************************************************************************/ #include "raylib.h" + #include "rlgl.h" -#include "math.h" // Used for tan() -#include "raymath.h" // Used to calculate camera Direction +#include "raymath.h" + +#include // Required for: tanf() #if defined(PLATFORM_DESKTOP) -#define GLSL_VERSION 330 + #define GLSL_VERSION 330 #else // PLATFORM_ANDROID, PLATFORM_WEB -#define GLSL_VERSION 100 + #define GLSL_VERSION 100 #endif +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +typedef struct { + unsigned int camPos; + unsigned int camDir; + unsigned int screenCenter; +} RayLocs; + //------------------------------------------------------------------------------------ -// Declare custom functions required for the example +// Module Functions Declaration //------------------------------------------------------------------------------------ // Load custom render texture, create a writable depth texture buffer static RenderTexture2D LoadRenderTextureDepthTex(int width, int height); // Unload render texture from GPU memory (VRAM) static void UnloadRenderTextureDepthTex(RenderTexture2D target); -//------------------------------------------------------------------------------------ -// Declare custom Structs -//------------------------------------------------------------------------------------ - -typedef struct { - unsigned int camPos, camDir, screenCenter; -}RayLocs ; - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -164,10 +167,10 @@ int main(void) } //------------------------------------------------------------------------------------ -// Define custom functions required for the example +// Module Functions Definition //------------------------------------------------------------------------------------ // Load custom render texture, create a writable depth texture buffer -RenderTexture2D LoadRenderTextureDepthTex(int width, int height) +static RenderTexture2D LoadRenderTextureDepthTex(int width, int height) { RenderTexture2D target = { 0 }; @@ -206,7 +209,7 @@ RenderTexture2D LoadRenderTextureDepthTex(int width, int height) } // Unload render texture from GPU memory (VRAM) -void UnloadRenderTextureDepthTex(RenderTexture2D target) +static void UnloadRenderTextureDepthTex(RenderTexture2D target) { if (target.id > 0) { diff --git a/examples/shaders/shaders_rounded_rectangle.c b/examples/shaders/shaders_rounded_rectangle.c index fd6433fc8..a1c5176f5 100644 --- a/examples/shaders/shaders_rounded_rectangle.c +++ b/examples/shaders/shaders_rounded_rectangle.c @@ -23,9 +23,9 @@ #define GLSL_VERSION 100 #endif -//------------------------------------------------------------------------------------ -// Structs definition -//------------------------------------------------------------------------------------ +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- // Rounded rectangle data typedef struct { Vector4 cornerRadius; // Individual corner radius (top-left, top-right, bottom-left, bottom-right) diff --git a/examples/shaders/shaders_spotlight.c b/examples/shaders/shaders_spotlight.c index c5075bd9f..74fbb2d4c 100644 --- a/examples/shaders/shaders_spotlight.c +++ b/examples/shaders/shaders_spotlight.c @@ -43,6 +43,9 @@ #define MAX_SPOTS 3 // NOTE: It must be the same as define in shader #define MAX_STARS 400 +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- // Spot data typedef struct Spot { Vector2 position; @@ -65,6 +68,9 @@ typedef struct Star { int screenWidth = 800; int screenHeight = 450; +//-------------------------------------------------------------------------------------- +// Module Functions Declaration +//-------------------------------------------------------------------------------------- static void UpdateStar(Star *s); static void ResetStar(Star *s); diff --git a/examples/shaders/shaders_write_depth.c b/examples/shaders/shaders_write_depth.c index a71a27d9d..8454fe097 100644 --- a/examples/shaders/shaders_write_depth.c +++ b/examples/shaders/shaders_write_depth.c @@ -25,9 +25,9 @@ #define GLSL_VERSION 100 #endif -//------------------------------------------------------------------------------------ -// Declare custom functions required for the example -//------------------------------------------------------------------------------------ +//-------------------------------------------------------------------------------------- +// Module Functions Declaration +//-------------------------------------------------------------------------------------- // Load custom render texture, create a writable depth texture buffer static RenderTexture2D LoadRenderTextureDepthTex(int width, int height); @@ -116,9 +116,10 @@ int main(void) return 0; } -//------------------------------------------------------------------------------------ -// Define custom functions required for the example -//------------------------------------------------------------------------------------ +//-------------------------------------------------------------------------------------- +// Module Functions Definition +//-------------------------------------------------------------------------------------- + // Load custom render texture, create a writable depth texture buffer RenderTexture2D LoadRenderTextureDepthTex(int width, int height) { diff --git a/examples/shapes/raygui.h b/examples/shapes/raygui.h index 85c477870..a3fc51f0f 100644 --- a/examples/shapes/raygui.h +++ b/examples/shapes/raygui.h @@ -1480,7 +1480,7 @@ static void DrawRectangleGradientV(int posX, int posY, int width, int height, Co #endif // RAYGUI_STANDALONE //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- static void GuiLoadStyleFromMemory(const unsigned char *fileData, int dataSize); // Load style from memory (binary only) @@ -4479,7 +4479,7 @@ void GuiSetIconScale(int scale) #endif // !RAYGUI_NO_ICONS //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- // Load style from memory diff --git a/examples/shapes/shapes_digital_clock.c b/examples/shapes/shapes_digital_clock.c index 5f13dd2a8..20c43ed7b 100644 --- a/examples/shapes/shapes_digital_clock.c +++ b/examples/shapes/shapes_digital_clock.c @@ -128,7 +128,6 @@ int main(void) //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- - // Update clock time static void UpdateClock(Clock *clock) { diff --git a/examples/shapes/shapes_double_pendulum.c b/examples/shapes/shapes_double_pendulum.c index ed3b36e8e..f1917f5af 100644 --- a/examples/shapes/shapes_double_pendulum.c +++ b/examples/shapes/shapes_double_pendulum.c @@ -183,13 +183,16 @@ int main(void) return 0; } -// Calculate Pendulum End Point +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- +// Calculate pendulum end point static Vector2 CalculatePendulumEndPoint(float l, float theta) { return (Vector2){ 10*l*sin(theta), 10*l*cos(theta) }; } -// Calculate Double Pendulum End Point +// Calculate double pendulum end point static Vector2 CalculateDoublePendulumEndPoint(float l1, float theta1, float l2, float theta2) { Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1); diff --git a/examples/shapes/shapes_rectangle_advanced.c b/examples/shapes/shapes_rectangle_advanced.c index c4fc648b3..5bd15cc55 100644 --- a/examples/shapes/shapes_rectangle_advanced.c +++ b/examples/shapes/shapes_rectangle_advanced.c @@ -21,6 +21,9 @@ #include +//-------------------------------------------------------------------------------------- +// Module Functions Declaration +//-------------------------------------------------------------------------------------- // Draw rectangle with rounded edges and horizontal gradient, with options to choose side of roundness static void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, float roundnessRight, int segments, Color left, Color right); @@ -83,6 +86,9 @@ int main(void) return 0; } +//-------------------------------------------------------------------------------------- +// Module Functions Definition +//-------------------------------------------------------------------------------------- // Draw rectangle with rounded edges and horizontal gradient, with options to choose side of roundness // NOTE: Adapted from both 'DrawRectangleRounded()' and 'DrawRectangleGradientH()' raylib [rshapes] implementations static void DrawRectangleRoundedGradientH(Rectangle rec, float roundnessLeft, float roundnessRight, int segments, Color left, Color right) diff --git a/examples/text/text_draw_3d.c b/examples/text/text_draw_3d.c index 028acb4c4..f3c403b99 100644 --- a/examples/text/text_draw_3d.c +++ b/examples/text/text_draw_3d.c @@ -41,7 +41,7 @@ #endif //-------------------------------------------------------------------------------------- -// Globals +// Global variables //-------------------------------------------------------------------------------------- #define LETTER_BOUNDRY_SIZE 0.25f #define TEXT_MAX_LAYERS 32 @@ -51,7 +51,7 @@ bool SHOW_LETTER_BOUNDRY = false; bool SHOW_TEXT_BOUNDRY = false; //-------------------------------------------------------------------------------------- -// Data Types definition +// Types and Structures Definition //-------------------------------------------------------------------------------------- // Configuration structure for waving the text typedef struct WaveTextConfig { diff --git a/examples/text/text_font_sdf.c b/examples/text/text_font_sdf.c index 5a24c1013..d81e8b447 100644 --- a/examples/text/text_font_sdf.c +++ b/examples/text/text_font_sdf.c @@ -50,7 +50,7 @@ int main(void) // Loading font data from memory data // Parameters > font size: 16, no glyphs array provided (0), glyphs count: 95 (autogenerate chars array) - fontDefault.glyphs = LoadFontData(fileData, fileSize, 16, 0, 95, FONT_DEFAULT); + fontDefault.glyphs = LoadFontData(fileData, fileSize, 16, 0, 95, FONT_DEFAULT, &fontDefault.glyphCount); // Parameters > glyphs count: 95, font size: 16, glyphs padding in image: 4 px, pack method: 0 (default) Image atlas = GenImageFontAtlas(fontDefault.glyphs, &fontDefault.recs, 95, 16, 4, 0); fontDefault.texture = LoadTextureFromImage(atlas); @@ -61,7 +61,8 @@ int main(void) fontSDF.baseSize = 16; fontSDF.glyphCount = 95; // Parameters > font size: 16, no glyphs array provided (0), glyphs count: 0 (defaults to 95) - fontSDF.glyphs = LoadFontData(fileData, fileSize, 16, 0, 0, FONT_SDF); + fontSDF.glyphs = LoadFontData(fileData, fileSize, 16, 0, 0, FONT_SDF, & + fontSDF.glyphCount); // Parameters > glyphs count: 95, font size: 16, glyphs padding in image: 0 px, pack method: 1 (Skyline algorythm) atlas = GenImageFontAtlas(fontSDF.glyphs, &fontSDF.recs, 95, 16, 0, 1); fontSDF.texture = LoadTextureFromImage(atlas); diff --git a/examples/text/text_rectangle_bounds.c b/examples/text/text_rectangle_bounds.c index 66fe53234..e180ae475 100644 --- a/examples/text/text_rectangle_bounds.c +++ b/examples/text/text_rectangle_bounds.c @@ -18,7 +18,7 @@ #include "raylib.h" //---------------------------------------------------------------------------------- -// Module functions declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- // Draw text using font inside rectangle limits static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); @@ -135,7 +135,7 @@ tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet ris } //-------------------------------------------------------------------------------------- -// Module functions definition +// Module Functions Definition //-------------------------------------------------------------------------------------- // Draw text using font inside rectangle limits diff --git a/examples/text/text_unicode.c b/examples/text/text_unicode.c index 54bdd4f86..aa8527fa9 100644 --- a/examples/text/text_unicode.c +++ b/examples/text/text_unicode.c @@ -24,6 +24,18 @@ #define EMOJI_PER_WIDTH 8 #define EMOJI_PER_HEIGHT 4 +//-------------------------------------------------------------------------------------- +// Global variables +//-------------------------------------------------------------------------------------- +// Arrays that holds the random emojis +struct { + int index; // Index inside `emojiCodepoints` + int message; // Message index + Color color; // Emoji color +} emoji[EMOJI_PER_WIDTH*EMOJI_PER_HEIGHT] = { 0 }; + +static int hovered = -1, selected = -1; + // String containing 180 emoji codepoints separated by a '\0' char const char *const emojiCodepoints = "\xF0\x9F\x8C\x80\x00\xF0\x9F\x98\x80\x00\xF0\x9F\x98\x82\x00\xF0\x9F\xA4\xA3\x00\xF0\x9F\x98\x83\x00\xF0\x9F\x98\x86\x00\xF0\x9F\x98\x89\x00" "\xF0\x9F\x98\x8B\x00\xF0\x9F\x98\x8E\x00\xF0\x9F\x98\x8D\x00\xF0\x9F\x98\x98\x00\xF0\x9F\x98\x97\x00\xF0\x9F\x98\x99\x00\xF0\x9F\x98\x9A\x00\xF0\x9F\x99\x82\x00" @@ -133,25 +145,13 @@ struct { }; //-------------------------------------------------------------------------------------- -// Module functions declaration +// Module Functions Declaration //-------------------------------------------------------------------------------------- static void RandomizeEmoji(void); // Fills the emoji array with random emojis static void DrawTextBoxed(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint); // Draw text using font inside rectangle limits static void DrawTextBoxedSelectable(Font font, const char *text, Rectangle rec, float fontSize, float spacing, bool wordWrap, Color tint, int selectStart, int selectLength, Color selectTint, Color selectBackTint); // Draw text using font inside rectangle limits with support for text selection -//-------------------------------------------------------------------------------------- -// Global variables -//-------------------------------------------------------------------------------------- -// Arrays that holds the random emojis -struct { - int index; // Index inside `emojiCodepoints` - int message; // Message index - Color color; // Emoji color -} emoji[EMOJI_PER_WIDTH*EMOJI_PER_HEIGHT] = { 0 }; - -static int hovered = -1, selected = -1; - //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ @@ -329,7 +329,7 @@ static void RandomizeEmoji(void) } //-------------------------------------------------------------------------------------- -// Module functions definition +// Module Functions Definition //-------------------------------------------------------------------------------------- // Draw text using font inside rectangle limits diff --git a/examples/text/text_unicode_ranges.c b/examples/text/text_unicode_ranges.c index d3cb4b5e5..76d20ba40 100644 --- a/examples/text/text_unicode_ranges.c +++ b/examples/text/text_unicode_ranges.c @@ -11,7 +11,7 @@ * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software * -* Copyright (c) 2019-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) +* Copyright (c) 2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5) * ********************************************************************************************/ @@ -19,17 +19,11 @@ #include -typedef struct { - int* data; - int count; - int capacity; -} CodepointsArray; - //-------------------------------------------------------------------------------------- -// Module functions declaration +// Module Functions Declaration //-------------------------------------------------------------------------------------- -static void AddRange(CodepointsArray* array, int start, int stop); -static Font LoadUnicodeFont(const char* fileName, int fontSize); +// Add codepoint range to existing font +static void AddCodepointRange(Font *font, const char *fontPath, int start, int stop); //------------------------------------------------------------------------------------ // Program main entry point @@ -43,9 +37,12 @@ int main(void) InitWindow(screenWidth, screenHeight, "raylib [text] example - unicode ranges"); - // Load font with Unicode support - Font fontUni = LoadUnicodeFont("resources/NotoSansTC-Regular.ttf", 32); - SetTextureFilter(fontUni.texture, TEXTURE_FILTER_BILINEAR); + // Load font with default Unicode range: Basic ASCII [32-127] + Font font = LoadFont("resources/NotoSansTC-Regular.ttf"); + SetTextureFilter(font.texture, TEXTURE_FILTER_BILINEAR); + + int unicodeRange = 0; // Track the ranges of codepoints added to font + int prevUnicodeRange = 0; // Previous Unicode range to avoid reloading every frame SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -55,7 +52,77 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - //... + if (unicodeRange != prevUnicodeRange) + { + UnloadFont(font); + + // Load font with default Unicode range: Basic ASCII [32-127] + font = LoadFont("resources/NotoSansTC-Regular.ttf"); + + // Add required ranges to loaded font + switch (unicodeRange) + { + /* + case 5: + { + // Unicode range: Devanari, Arabic, Hebrew + // WARNING: Glyphs not available on provided font! + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x900, 0x97f); // Devanagari + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x600, 0x6ff); // Arabic + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x5d0, 0x5ea); // Hebrew + } + */ + case 4: + { + // Unicode range: CJK (Japanese and Chinese) + // WARNING: Loading thousands of codepoints requires lot of time! + // A better strategy is prefilter the required codepoints for the text + // in the game and just load the required ones + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x4e00, 0x9fff); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x3400, 0x4dbf); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x3000, 0x303f); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x3040, 0x309f); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x30A0, 0x30ff); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x31f0, 0x31ff); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0xff00, 0xffef); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0xac00, 0xd7af); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x1100, 0x11ff); + } + case 3: + { + // Unicode range: Cyrillic + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x400, 0x4ff); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x500, 0x52f); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x2de0, 0x2Dff); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0xa640, 0xA69f); + } + case 2: + { + // Unicode range: Greek + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x370, 0x3ff); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x1f00, 0x1fff); + } + case 1: + { + // Unicode range: European Languages + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0xc0, 0x17f); + AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x180, 0x24f); + //AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x1e00, 0x1eff); + //AddCodepointRange(&font, "resources/NotoSansTC-Regular.ttf", 0x2c60, 0x2c7f); + } + default: break; + } + + prevUnicodeRange = unicodeRange; + SetTextureFilter(font.texture, TEXTURE_FILTER_BILINEAR); // Set font atlas scale filter + } + + if (IsKeyPressed(KEY_ZERO)) unicodeRange = 0; + else if (IsKeyPressed(KEY_ONE)) unicodeRange = 1; + else if (IsKeyPressed(KEY_TWO)) unicodeRange = 2; + else if (IsKeyPressed(KEY_THREE)) unicodeRange = 3; + else if (IsKeyPressed(KEY_FOUR)) unicodeRange = 4; + //else if (IsKeyPressed(KEY_FIVE)) unicodeRange = 5; //---------------------------------------------------------------------------------- // Draw @@ -63,22 +130,36 @@ int main(void) BeginDrawing(); ClearBackground(RAYWHITE); + + DrawText("ADD CODEPOINTS: [1][2][3][4]", 20, 20, 20, MAROON); // Render test strings in different languages - DrawTextEx(fontUni, "English: Hello World!", (Vector2){ 50, 50 }, 32, 1, DARKGRAY); // English - DrawTextEx(fontUni, "Español: Hola mundo!", (Vector2){ 50, 100 }, 32, 1, DARKGRAY); // Spanish - DrawTextEx(fontUni, "Ελληνικά: Γειά σου κόσμε!", (Vector2){ 50, 150 }, 32, 1, DARKGRAY); // Greek - DrawTextEx(fontUni, "Русский: Привет мир!", (Vector2){ 50, 200 }, 32, 0, DARKGRAY); // Russian - DrawTextEx(fontUni, "中文: 你好世界!", (Vector2){ 50, 250 }, 32, 1, DARKGRAY); // Chinese - DrawTextEx(fontUni, "日本語: こんにちは世界!", (Vector2){ 50, 300 }, 32, 1, DARKGRAY); // Japanese - DrawTextEx(fontUni, "देवनागरी: होला मुंडो!", (Vector2){ 50, 350 }, 32, 1, DARKGRAY); // Devanagari + DrawTextEx(font, "> English: Hello World!", (Vector2){ 50, 70 }, 32, 1, DARKGRAY); // English + DrawTextEx(font, "> Español: Hola mundo!", (Vector2){ 50, 120 }, 32, 1, DARKGRAY); // Spanish + DrawTextEx(font, "> Ελληνικά: Γειά σου κόσμε!", (Vector2){ 50, 170 }, 32, 1, DARKGRAY); // Greek + DrawTextEx(font, "> Русский: Привет мир!", (Vector2){ 50, 220 }, 32, 0, DARKGRAY); // Russian + DrawTextEx(font, "> 中文: 你好世界!", (Vector2){ 50, 270 }, 32, 1, DARKGRAY); // Chinese + DrawTextEx(font, "> 日本語: こんにちは世界!", (Vector2){ 50, 320 }, 32, 1, DARKGRAY); // Japanese + //DrawTextEx(font, "देवनागरी: होला मुंडो!", (Vector2){ 50, 350 }, 32, 1, DARKGRAY); // Devanagari (glyphs not available in font) - DrawRectangle(400, 16, 380, 400, BLACK); - DrawTexturePro(fontUni.texture, (Rectangle){ 0, 0, fontUni.texture.width, fontUni.texture.height }, - (Rectangle){ 400, 16, 380, 400 }, (Vector2){ 0, 0 }, 0.0f, WHITE); + // Draw font texture scaled to screen + float atlasScale = 380.0f/font.texture.width; + DrawRectangle(400, 16, font.texture.width*atlasScale, font.texture.height*atlasScale, BLACK); + DrawTexturePro(font.texture, (Rectangle){ 0, 0, font.texture.width, font.texture.height }, + (Rectangle){ 400, 16, font.texture.width*atlasScale, font.texture.height*atlasScale }, (Vector2){ 0, 0 }, 0.0f, WHITE); + DrawRectangleLines(400, 16, 380, 380, RED); + + DrawText(TextFormat("ATLAS SIZE: %ix%i px (x%02.1f)", font.texture.width, font.texture.height, atlasScale), 20, 380, 20, BLUE); // Display font attribution DrawText("Font: Noto Sans TC. License: SIL Open Font License 1.1", screenWidth - 300, screenHeight - 20, 10, GRAY); + + if (prevUnicodeRange != unicodeRange) + { + DrawRectangle(0, 0, screenWidth, screenHeight, Fade(WHITE, 0.8f)); + DrawRectangle(0, 125, screenWidth, 200, GRAY); + DrawText("LOADING CODEPOINTS...", 150, 210, 40, BLACK); + } EndDrawing(); //---------------------------------------------------------------------------------- @@ -86,7 +167,7 @@ int main(void) // De-Initialization //-------------------------------------------------------------------------------------- - UnloadFont(fontUni); // Unload font resource + UnloadFont(font); // Unload font resource CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- @@ -95,89 +176,28 @@ int main(void) } //-------------------------------------------------------------------------------------- -// Module functions definition +// Module Functions Definition //-------------------------------------------------------------------------------------- -static void AddRange(CodepointsArray* array, int start, int stop) +// Add codepoint range to existing font +static void AddCodepointRange(Font *font, const char *fontPath, int start, int stop) { int rangeSize = stop - start + 1; + int currentRangeSize = font->glyphCount; - if ((array->count + rangeSize) > array->capacity) - { - array->capacity = array->count + rangeSize + 1024; - array->data = (int *)MemRealloc(array->data, array->capacity*sizeof(int)); - - if (!array->data) - { - TraceLog(LOG_ERROR, "FONTUTIL: Memory allocation failed"); - exit(1); - } - } + // TODO: Load glyphs from provided vector font (if available), + // add them to existing font, regenerating font image and texture - for (int i = start; i <= stop; i++) array->data[array->count++] = i; + int updatedCodepointCount = currentRangeSize + rangeSize; + int *updatedCodepoints = (int *)RL_CALLOC(updatedCodepointCount, sizeof(int)); + + // Get current codepoint list + for (int i = 0; i < currentRangeSize; i++) updatedCodepoints[i] = font->glyphs[i].value; + + // Add new codepoints to list (provided range) + for (int i = currentRangeSize; i < updatedCodepointCount; i++) + updatedCodepoints[i] = start + (i - currentRangeSize); + + UnloadFont(*font); + *font = LoadFontEx(fontPath, 32, updatedCodepoints, updatedCodepointCount); } -Font LoadUnicodeFont(const char *fileName, int fontSize) -{ - CodepointsArray cp = { 0 }; - cp.capacity = 2048; - cp.data = (int *)MemAlloc(cp.capacity*sizeof(int)); - - if (!cp.data) - { - TraceLog(LOG_ERROR, "FONTUTIL: Initial allocation failed"); - return GetFontDefault(); - } - - // Unicode range: Basic ASCII - AddRange(&cp, 32, 126); - - // Unicode range: European Languages - AddRange(&cp, 0xC0, 0x17F); - AddRange(&cp, 0x180, 0x24F); - AddRange(&cp, 0x1E00, 0x1EFF); - AddRange(&cp, 0x2C60, 0x2C7F); - - // Unicode range: Greek - AddRange(&cp, 0x370, 0x3FF); - AddRange(&cp, 0x1F00, 0x1FFF); - - // Unicode range: Cyrillic - AddRange(&cp, 0x400, 0x4FF); - AddRange(&cp, 0x500, 0x52F); - AddRange(&cp, 0x2DE0, 0x2DFF); - AddRange(&cp, 0xA640, 0xA69F); - - // Unicode range: CJK - AddRange(&cp, 0x4E00, 0x9FFF); - AddRange(&cp, 0x3400, 0x4DBF); - AddRange(&cp, 0x3000, 0x303F); - AddRange(&cp, 0x3040, 0x309F); - AddRange(&cp, 0x30A0, 0x30FF); - AddRange(&cp, 0x31F0, 0x31FF); - AddRange(&cp, 0xFF00, 0xFFEF); - AddRange(&cp, 0xAC00, 0xD7AF); - AddRange(&cp, 0x1100, 0x11FF); - - // Unicode range: Other - // WARNING: Not available on provided font - AddRange(&cp, 0x900, 0x97F); // Devanagari - AddRange(&cp, 0x600, 0x6FF); // Arabic - AddRange(&cp, 0x5D0, 0x5EA); // Hebrew - - Font font = {0}; - - if (FileExists(fileName)) - { - font = LoadFontEx(fileName, fontSize, cp.data, cp.count); - } - - if (font.texture.id == 0) - { - font = GetFontDefault(); - TraceLog(LOG_WARNING, "FONTUTIL: Using default font"); - } - - MemFree(cp.data); - - return font; -} diff --git a/examples/text/text_unicode_ranges.png b/examples/text/text_unicode_ranges.png new file mode 100644 index 000000000..5ffffe718 Binary files /dev/null and b/examples/text/text_unicode_ranges.png differ diff --git a/examples/textures/textures_image_kernel.c b/examples/textures/textures_image_kernel.c index 99285e15e..3c89bd620 100644 --- a/examples/textures/textures_image_kernel.c +++ b/examples/textures/textures_image_kernel.c @@ -20,7 +20,7 @@ #include "raylib.h" //------------------------------------------------------------------------------------ -// Module functions declaration +// Module Functions Declaration //------------------------------------------------------------------------------------ static void NormalizeKernel(float *kernel, int size); @@ -131,7 +131,7 @@ int main(void) } //------------------------------------------------------------------------------------ -// Module functions definition +// Module Functions Definition //------------------------------------------------------------------------------------ static void NormalizeKernel(float *kernel, int size) { diff --git a/examples/textures/textures_textured_curve.c b/examples/textures/textures_textured_curve.c index 245aee3c7..feeefc7b6 100644 --- a/examples/textures/textures_textured_curve.c +++ b/examples/textures/textures_textured_curve.c @@ -155,7 +155,6 @@ int main() //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- - // Draw textured curve using Spline Cubic Bezier static void DrawTexturedCurve(void) { diff --git a/projects/CMake/core_basic_window.c b/projects/CMake/core_basic_window.c index 86709f7a9..cb23a6f87 100644 --- a/projects/CMake/core_basic_window.c +++ b/projects/CMake/core_basic_window.c @@ -31,7 +31,7 @@ int screenHeight = 450; void UpdateDrawFrame(void); // Update and Draw one frame //---------------------------------------------------------------------------------- -// Main Entry Point +// Program main entry point //---------------------------------------------------------------------------------- int main() { diff --git a/projects/VS2022/examples/core_3d_fps_controller.vcxproj b/projects/VS2022/examples/core_3d_camera_fps.vcxproj similarity index 100% rename from projects/VS2022/examples/core_3d_fps_controller.vcxproj rename to projects/VS2022/examples/core_3d_camera_fps.vcxproj diff --git a/projects/VS2022/examples/text_unicode_ranges.vcxproj b/projects/VS2022/examples/text_unicode_ranges.vcxproj index c9ddd9a1c..730bcb1d0 100644 --- a/projects/VS2022/examples/text_unicode_ranges.vcxproj +++ b/projects/VS2022/examples/text_unicode_ranges.vcxproj @@ -51,7 +51,7 @@ - {6B1A933E-71B8-4C1F-9E79-02D98830E671} + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} Win32Proj text_unicode_ranges 10.0 diff --git a/projects/VS2022/raylib.sln b/projects/VS2022/raylib.sln index 21d7c63b6..227d52297 100644 --- a/projects/VS2022/raylib.sln +++ b/projects/VS2022/raylib.sln @@ -337,7 +337,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core_3d_camera_fps", "examp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shaders_normal_map", "examples\shaders_normal_map.vcxproj", "{6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_unicode_ranges", "examples\text_unicode_ranges.vcxproj", "{6B1A933E-71B8-4C1F-9E79-02D98830E671}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "text_unicode_ranges", "examples\text_unicode_ranges.vcxproj", "{6777EC3C-077C-42FC-B4AD-B799CE55CCE4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -4135,30 +4135,30 @@ Global {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x64.Build.0 = Release|x64 {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.ActiveCfg = Release|Win32 {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3}.Release|x86.Build.0 = Release|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|ARM64.Build.0 = Debug|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.ActiveCfg = Debug|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x64.Build.0 = Debug|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.ActiveCfg = Debug|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Debug|x86.Build.0 = Debug|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x64.Build.0 = Release.DLL|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release.DLL|x86.Build.0 = Release.DLL|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.ActiveCfg = Release|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|ARM64.Build.0 = Release|ARM64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.ActiveCfg = Release|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x64.Build.0 = Release|x64 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.ActiveCfg = Release|Win32 - {6B1A933E-71B8-4C1F-9E79-02D98830E671}.Release|x86.Build.0 = Release|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|ARM64.ActiveCfg = Debug.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|ARM64.Build.0 = Debug.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x64.ActiveCfg = Debug.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x64.Build.0 = Debug.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x86.ActiveCfg = Debug.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug.DLL|x86.Build.0 = Debug.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|ARM64.Build.0 = Debug|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x64.ActiveCfg = Debug|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x64.Build.0 = Debug|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x86.ActiveCfg = Debug|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Debug|x86.Build.0 = Debug|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|ARM64.ActiveCfg = Release.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|ARM64.Build.0 = Release.DLL|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x64.ActiveCfg = Release.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x64.Build.0 = Release.DLL|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x86.ActiveCfg = Release.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release.DLL|x86.Build.0 = Release.DLL|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|ARM64.ActiveCfg = Release|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|ARM64.Build.0 = Release|ARM64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x64.ActiveCfg = Release|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x64.Build.0 = Release|x64 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x86.ActiveCfg = Release|Win32 + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -4327,9 +4327,9 @@ Global {C54703BF-D68A-480D-BE27-49B62E45D582} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} {9CD8BCAD-F212-4BCC-BA98-899743CE3279} = {CC132A4D-D081-4C26-BFB9-AB11984054F8} {0981CA28-E4A5-4DF1-987F-A41D09131EFC} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} + {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {6C82BAAE-BDDF-457D-8FA8-7E2490B07035} {6BFF72EA-7362-4A3B-B6E5-9A3655BBBDA3} = {5317807F-61D4-4E0F-B6DC-2D9F12621ED9} - {6B1A933E-71B8-4C1F-9E79-02D98830E671} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} + {6777EC3C-077C-42FC-B4AD-B799CE55CCE4} = {8D3C83B7-F1E0-4C2E-9E34-EE5F6AB2502A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E926C768-6307-4423-A1EC-57E95B1FAB29} diff --git a/projects/VSCode/main.c b/projects/VSCode/main.c index cad32c2ef..ea394de58 100644 --- a/projects/VSCode/main.c +++ b/projects/VSCode/main.c @@ -26,18 +26,18 @@ #endif //---------------------------------------------------------------------------------- -// Local Variables Definition (local to this module) +// Global Variables Definition (local to this module) //---------------------------------------------------------------------------------- Camera camera = { 0 }; Vector3 cubePosition = { 0 }; //---------------------------------------------------------------------------------- -// Local Functions Declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- static void UpdateDrawFrame(void); // Update and draw one frame //---------------------------------------------------------------------------------- -// Main entry point +// Program main entry point //---------------------------------------------------------------------------------- int main() { diff --git a/src/external/rprand.h b/src/external/rprand.h index 95147d270..cdef03c01 100644 --- a/src/external/rprand.h +++ b/src/external/rprand.h @@ -156,13 +156,13 @@ static uint32_t rprand_state[4] = { // Xoshiro128** state, initializ }; //---------------------------------------------------------------------------------- -// Module internal functions declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- static uint32_t rprand_xoshiro(void); // Xoshiro128** generator (uses global rprand_state) static uint64_t rprand_splitmix64(void); // SplitMix64 generator (uses seed to generate rprand_state) //---------------------------------------------------------------------------------- -// Module functions definition +// Module Functions Definition //---------------------------------------------------------------------------------- // Set rprand_state for Xoshiro128** // NOTE: We use a custom generation algorithm using SplitMix64 @@ -236,7 +236,7 @@ void rprand_unload_sequence(int *sequence) } //---------------------------------------------------------------------------------- -// Module internal functions definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- static inline uint32_t rprand_rotate_left(const uint32_t x, int k) { diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index c9b346fcf..33788d720 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -111,7 +111,7 @@ extern CoreData CORE; // Global CORE state context static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- -// Local Variables Definition +// Global Variables Definition //---------------------------------------------------------------------------------- #define SCANCODE_MAPPED_NUM 232 static const KeyboardKey mapScancodeToKey[SCANCODE_MAPPED_NUM] = { diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index a2151ea38..b15df2dea 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -156,7 +156,7 @@ extern CoreData CORE; // Global CORE state context static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- -// Local Variables Definition +// Global Variables Definition //---------------------------------------------------------------------------------- // NOTE: The complete evdev EV_KEY list can be found at /usr/include/linux/input-event-codes.h diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 2712aa142..a32f9c59a 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -86,7 +86,7 @@ extern CoreData CORE; // Global CORE state context static PlatformData platform = { 0 }; // Platform specific data //---------------------------------------------------------------------------------- -// Local Variables Definition +// Global Variables Definition //---------------------------------------------------------------------------------- static const char cursorLUT[11][12] = { "default", // 0 MOUSE_CURSOR_DEFAULT diff --git a/src/raudio.c b/src/raudio.c index e9d76fa99..c883132d9 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -407,7 +407,7 @@ static AudioData AUDIO = { // Global AUDIO context }; //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage); @@ -2352,9 +2352,8 @@ void DetachAudioMixedProcessor(AudioCallback process) } //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- - // Log callback function static void OnLog(void *pUserData, ma_uint32 level, const char *pMessage) { diff --git a/src/raylib.h b/src/raylib.h index c45168763..41bc1926e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -115,7 +115,7 @@ #endif //---------------------------------------------------------------------------------- -// Some basic Defines +// Defines and Macros //---------------------------------------------------------------------------------- #ifndef PI #define PI 3.14159265358979323846f @@ -201,7 +201,7 @@ #define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo) //---------------------------------------------------------------------------------- -// Structures Definition +// Types and Structures Definition //---------------------------------------------------------------------------------- // Boolean type #if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800) @@ -327,7 +327,7 @@ typedef struct Camera3D { Vector3 position; // Camera position Vector3 target; // Camera target it looks-at Vector3 up; // Camera up vector (rotation over its axis) - float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic + float fovy; // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic int projection; // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC } Camera3D; @@ -1470,7 +1470,7 @@ RLAPI Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style) RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf' RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked) -RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use +RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount, int type, int *glyphCount); // Load font data for further use RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM) RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM) diff --git a/src/rcamera.h b/src/rcamera.h index 62c1225ec..3e9f83095 100644 --- a/src/rcamera.h +++ b/src/rcamera.h @@ -216,7 +216,7 @@ RLAPI Matrix GetCameraProjectionMatrix(Camera *camera, float aspect); //... //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- //... diff --git a/src/rcore.c b/src/rcore.c index 4360a23ee..d1b1a8219 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -2562,19 +2562,20 @@ unsigned char *DecompressData(const unsigned char *compData, int compDataSize, i #if defined(SUPPORT_COMPRESSION_API) // Decompress data from a valid DEFLATE stream - data = (unsigned char *)RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1); + unsigned char *data0 = (unsigned char *)RL_CALLOC(MAX_DECOMPRESSION_SIZE*1024*1024, 1); int length = sinflate(data, MAX_DECOMPRESSION_SIZE*1024*1024, compData, compDataSize); - // WARNING: RL_REALLOC can make (and leave) data copies in memory, be careful with sensitive compressed data! - // TODO: Use a different approach, create another buffer, copy data manually to it and wipe original buffer memory - unsigned char *temp = (unsigned char *)RL_REALLOC(data, length); - - if (temp != NULL) data = temp; - else TRACELOG(LOG_WARNING, "SYSTEM: Failed to re-allocate required decompression memory"); + // WARNING: RL_REALLOC can make (and leave) data copies in memory, + // that can be a security concern in case of compression of sensitive data + // So, we use a second buffer to copy data manually, wiping original buffer memory + data = (unsigned char *)RL_CALLOC(length, 1); + memcpy(data, data0, length); + memset(data0, 0, MAX_DECOMPRESSION_SIZE*1024*1024); // Wipe memory, is memset() safe? + RL_FREE(data0); + + TRACELOG(LOG_INFO, "SYSTEM: Decompress data: Comp. size: %i -> Original size: %i", compDataSize, length); *dataSize = length; - - TRACELOG(LOG_INFO, "SYSTEM: Decompress data: Comp. size: %i -> Original size: %i", compDataSize, *dataSize); #endif return data; diff --git a/src/rgestures.h b/src/rgestures.h index 1bf4e0555..389df64a1 100644 --- a/src/rgestures.h +++ b/src/rgestures.h @@ -238,7 +238,7 @@ static GesturesData GESTURES = { }; //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- static float rgVector2Angle(Vector2 initialPosition, Vector2 finalPosition); static float rgVector2Distance(Vector2 v1, Vector2 v2); @@ -481,7 +481,7 @@ float GetGesturePinchAngle(void) } //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- // Get angle from two-points vector with X-axis static float rgVector2Angle(Vector2 v1, Vector2 v2) diff --git a/src/rlgl.h b/src/rlgl.h index 324d8aac5..884110c56 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -1039,7 +1039,7 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad #endif //---------------------------------------------------------------------------------- -// Types and Structures Definition +// Module Types and Structures Definition //---------------------------------------------------------------------------------- #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) @@ -1145,7 +1145,7 @@ static PFNGLVERTEXATTRIBDIVISOREXTPROC glVertexAttribDivisor = NULL; #endif //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Functions Declaration //---------------------------------------------------------------------------------- #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) static void rlLoadShaderDefault(void); // Load default shader @@ -4864,7 +4864,7 @@ const char *rlGetPixelFormatName(unsigned int format) } //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Functions Definition //---------------------------------------------------------------------------------- #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2) // Load default shader (just vertex positioning and texture coloring) diff --git a/src/rmodels.c b/src/rmodels.c index ff71b79d6..3ac416847 100644 --- a/src/rmodels.c +++ b/src/rmodels.c @@ -144,7 +144,7 @@ // ... //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- #if defined(SUPPORT_FILEFORMAT_OBJ) static Model LoadOBJ(const char *fileName); // Load OBJ mesh data @@ -171,7 +171,6 @@ static void ProcessMaterialsOBJ(Material *rayMaterials, tinyobj_material_t *mate //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- - // Draw a line in 3D world space void DrawLine3D(Vector3 startPos, Vector3 endPos, Color color) { @@ -4244,7 +4243,7 @@ RayCollision GetRayCollisionQuad(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3, Ve } //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- #if defined(SUPPORT_FILEFORMAT_IQM) || defined(SUPPORT_FILEFORMAT_GLTF) // Build pose from parent joints @@ -6573,13 +6572,23 @@ static Model LoadM3D(const char *fileName) // Materials are grouped together if (mi != m3d->face[i].materialid) { - // there should be only one material switch per material kind, but be bulletproof for non-optimal model files + // There should be only one material switch per material kind, + // but be bulletproof for non-optimal model files if (k + 1 >= model.meshCount) { model.meshCount++; - model.meshes = (Mesh *)RL_REALLOC(model.meshes, model.meshCount*sizeof(Mesh)); - memset(&model.meshes[model.meshCount - 1], 0, sizeof(Mesh)); - model.meshMaterial = (int *)RL_REALLOC(model.meshMaterial, model.meshCount*sizeof(int)); + + // Create a second buffer for mesh re-allocation + Mesh *tempMeshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh)); + memcpy(tempMeshes, model.meshes, (model.meshCount - 1)*sizeof(Mesh)); + RL_FREE(model.meshes); + model.meshes = tempMeshes; + + // Create a second buffer for material re-allocation + int *tempMeshMaterial = (int *)RL_CALLOC(model.meshCount, sizeof(int)); + memcpy(tempMeshMaterial, model.meshMaterial, (model.meshCount - 1)*sizeof(int)); + RL_FREE(model.meshMaterial); + model.meshMaterial = tempMeshMaterial; } k++; diff --git a/src/rshapes.c b/src/rshapes.c index 38ad75c7d..14e3f856a 100644 --- a/src/rshapes.c +++ b/src/rshapes.c @@ -83,14 +83,13 @@ static Texture2D texShapes = { 1, 1, 1, 1, 7 }; // Texture used o static Rectangle texShapesRec = { 0.0f, 0.0f, 1.0f, 1.0f }; // Texture source rectangle used on shapes drawing //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- static float EaseCubicInOut(float t, float b, float c, float d); // Cubic easing //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- - // Set texture and rectangle to be used on shapes drawing // NOTE: It can be useful when using basic shapes and one single font, // defining a font char white rectangle would allow drawing everything in a single draw call @@ -2371,7 +2370,7 @@ bool CheckCollisionPointLine(Vector2 point, Vector2 p1, Vector2 p2, int threshol } // Check if circle collides with a line created between two points [p1] and [p2] -RLAPI bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2) +bool CheckCollisionCircleLine(Vector2 center, float radius, Vector2 p1, Vector2 p2) { float dx = p1.x - p2.x; float dy = p1.y - p2.y; @@ -2420,7 +2419,7 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2) } //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- // Cubic easing in-out diff --git a/src/rtext.c b/src/rtext.c index db143b098..009a264f3 100644 --- a/src/rtext.c +++ b/src/rtext.c @@ -141,7 +141,7 @@ static int textLineSpacing = 2; // Text vertical line spacing in //... //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- #if defined(SUPPORT_FILEFORMAT_FNT) static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file) @@ -171,7 +171,7 @@ extern void LoadFontDefault(void) // NOTE: Using UTF-8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement // Ref: http://www.utf8-chartable.de/unicode-utf8-table.pl - defaultFont.glyphCount = 224; // Number of chars included in our default font + defaultFont.glyphCount = 224; // Number of glyphs included in our default font defaultFont.glyphPadding = 0; // Characters padding // Default font is directly defined here (data generated from a sprite font image) @@ -365,7 +365,7 @@ Font LoadFont(const char *fileName) #define FONT_TTF_DEFAULT_FIRST_CHAR 32 // TTF font generation default first char for image sprite font (32-Space) #endif #ifndef FONT_TTF_DEFAULT_CHARS_PADDING - #define FONT_TTF_DEFAULT_CHARS_PADDING 4 // TTF font generation default chars padding + #define FONT_TTF_DEFAULT_CHARS_PADDING 4 // TTF font generation default glyphs padding #endif Font font = { 0 }; @@ -440,8 +440,8 @@ Font LoadFontFromImage(Image image, Color key, int firstChar) int x = 0; int y = 0; - // We allocate a temporal arrays for chars data measures, - // once we get the actual number of chars, we copy data to a sized arrays + // We allocate a temporal arrays for glyphs data measures, + // once we get the actual number of glyphs, we copy data to a sized arrays int tempCharValues[MAX_GLYPHS_FROM_IMAGE] = { 0 }; Rectangle tempCharRecs[MAX_GLYPHS_FROM_IMAGE] = { 0 }; @@ -520,7 +520,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar) font.glyphCount = index; font.glyphPadding = 0; - // We got tempCharValues and tempCharsRecs populated with chars data + // We got tempCharValues and tempCharsRecs populated with glyphs data // Now we move temp data to sized charValues and charRecs arrays font.glyphs = (GlyphInfo *)RL_MALLOC(font.glyphCount*sizeof(GlyphInfo)); font.recs = (Rectangle *)RL_MALLOC(font.glyphCount*sizeof(Rectangle)); @@ -557,21 +557,21 @@ Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int strncpy(fileExtLower, TextToLower(fileType), 16 - 1); font.baseSize = fontSize; - font.glyphCount = (codepointCount > 0)? codepointCount : 95; font.glyphPadding = 0; #if defined(SUPPORT_FILEFORMAT_TTF) if (TextIsEqual(fileExtLower, ".ttf") || TextIsEqual(fileExtLower, ".otf")) { - font.glyphs = LoadFontData(fileData, dataSize, font.baseSize, codepoints, font.glyphCount, FONT_DEFAULT); + font.glyphs = LoadFontData(fileData, dataSize, font.baseSize, codepoints, (codepointCount > 0)? codepointCount : 95, FONT_DEFAULT, &font.glyphCount); } else #endif #if defined(SUPPORT_FILEFORMAT_BDF) if (TextIsEqual(fileExtLower, ".bdf")) { - font.glyphs = LoadFontDataBDF(fileData, dataSize, codepoints, font.glyphCount, &font.baseSize); + font.glyphs = LoadFontDataBDF(fileData, dataSize, codepoints, (codepointCount > 0)? codepointCount : 95, &font.baseSize); + font.glyphCount = (codepointCount > 0)? codepointCount : 95; } else #endif @@ -620,7 +620,7 @@ bool IsFontValid(Font font) // Load font data for further use // NOTE: Requires TTF font memory data and can generate SDF data -GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type) +GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount, int type, int *glyphCount) { // NOTE: Using some SDF generation default values, // trades off precision with ability to handle *smaller* sizes @@ -637,7 +637,8 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz #define FONT_BITMAP_ALPHA_THRESHOLD 80 // Bitmap (B&W) font generation alpha threshold #endif - GlyphInfo *chars = NULL; + GlyphInfo *glyphs = NULL; + int glyphCounter = 0; #if defined(SUPPORT_FILEFORMAT_TTF) // Load font data (including pixel data) from TTF memory file @@ -646,6 +647,7 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz { bool genFontChars = false; stbtt_fontinfo fontInfo = { 0 }; + int *requiredCodepoints = (int *)codepoints; if (stbtt_InitFont(&fontInfo, (unsigned char *)fileData, 0)) // Initialize font for data reading { @@ -662,21 +664,29 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Fill fontChars in case not provided externally // NOTE: By default we fill glyphCount consecutively, starting at 32 (Space) - if (codepoints == NULL) + if (requiredCodepoints == NULL) { - codepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); - for (int i = 0; i < codepointCount; i++) codepoints[i] = i + 32; + requiredCodepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); + for (int i = 0; i < codepointCount; i++) requiredCodepoints[i] = i + 32; genFontChars = true; } - chars = (GlyphInfo *)RL_CALLOC(codepointCount, sizeof(GlyphInfo)); + // Check available glyphs on provided font before loading them + for (int i = 0, index; i < codepointCount; i++) + { + index = stbtt_FindGlyphIndex(&fontInfo, requiredCodepoints[i]); + if (index > 0) glyphCounter++; + } - // NOTE: Using simple packaging, one char after another + // WARNING: Allocating space for maximum number of codepoints + glyphs = (GlyphInfo *)RL_CALLOC(glyphCounter, sizeof(GlyphInfo)); + glyphCounter = 0; // Reset to reuse + + int k = 0; for (int i = 0; i < codepointCount; i++) { - int chw = 0, chh = 0; // Character width and height (on generation) - int ch = codepoints[i]; // Character value to get info for - chars[i].value = ch; + int cpWidth = 0, cpHeight = 0; // Codepoint width and height (on generation) + int cp = requiredCodepoints[i]; // Codepoint value to get info for // Render a unicode codepoint to a bitmap // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap @@ -685,76 +695,96 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz // Check if a glyph is available in the font // WARNING: if (index == 0), glyph not found, it could fallback to default .notdef glyph (if defined in font) - int index = stbtt_FindGlyphIndex(&fontInfo, ch); + int index = stbtt_FindGlyphIndex(&fontInfo, cp); if (index > 0) { + // NOTE: Only storing glyphs for codepoints found in the font + glyphs[k].value = cp; + switch (type) { case FONT_DEFAULT: - case FONT_BITMAP: chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break; - case FONT_SDF: if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break; + case FONT_BITMAP: glyphs[k].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, cp, &cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY); break; + case FONT_SDF: + { + if (cp != 32) + { + glyphs[k].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, cp, + FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, + &cpWidth, &cpHeight, &glyphs[k].offsetX, &glyphs[k].offsetY); + } + } break; + //case FONT_MSDF: default: break; } - if (chars[i].image.data != NULL) // Glyph data has been found in the font + if (glyphs[k].image.data != NULL) // Glyph data has been found in the font { - stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL); - chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor); + stbtt_GetCodepointHMetrics(&fontInfo, cp, &glyphs[k].advanceX, NULL); + glyphs[k].advanceX = (int)((float)glyphs[k].advanceX*scaleFactor); - if (chh > fontSize) TRACELOG(LOG_WARNING, "FONT: Character [0x%08x] size is bigger than expected font size", ch); + if (cpHeight > fontSize) TRACELOG(LOG_WARNING, "FONT: [0x%04x] Glyph height is bigger than requested font size: %i > %i", cp, cpHeight, (int)fontSize); - // Load characters images - chars[i].image.width = chw; - chars[i].image.height = chh; - chars[i].image.mipmaps = 1; - chars[i].image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; + // Load glyph image + glyphs[k].image.width = cpWidth; + glyphs[k].image.height = cpHeight; + glyphs[k].image.mipmaps = 1; + glyphs[k].image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; - chars[i].offsetY += (int)((float)ascent*scaleFactor); + glyphs[k].offsetY += (int)((float)ascent*scaleFactor); } + //else TRACELOG(LOG_WARNING, "FONT: Glyph [0x%08x] has no image data available", cp); // Only reported for 0x20 and 0x3000 - // NOTE: We create an empty image for space character, - // it could be further required for atlas packing - if (ch == 32) + // We create an empty image for Space character (0x20), useful for sprite font generation + // NOTE: Another space to consider: 0x3000 (CJK - Ideographic Space) + if ((cp == 0x20) || (cp == 0x3000)) { - stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL); - chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor); + stbtt_GetCodepointHMetrics(&fontInfo, cp, &glyphs[k].advanceX, NULL); + glyphs[k].advanceX = (int)((float)glyphs[k].advanceX*scaleFactor); Image imSpace = { - .data = RL_CALLOC(chars[i].advanceX*fontSize, 2), - .width = chars[i].advanceX, + .data = RL_CALLOC(glyphs[k].advanceX*fontSize, 2), + .width = glyphs[k].advanceX, .height = fontSize, .mipmaps = 1, .format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE }; - chars[i].image = imSpace; + glyphs[k].image = imSpace; } if (type == FONT_BITMAP) { // Aliased bitmap (black & white) font generation, avoiding anti-aliasing // NOTE: For optimum results, bitmap font should be generated at base pixel size - for (int p = 0; p < chw*chh; p++) + for (int p = 0; p < cpWidth*cpHeight; p++) { - if (((unsigned char *)chars[i].image.data)[p] < FONT_BITMAP_ALPHA_THRESHOLD) ((unsigned char *)chars[i].image.data)[p] = 0; - else ((unsigned char *)chars[i].image.data)[p] = 255; + if (((unsigned char *)glyphs[k].image.data)[p] < FONT_BITMAP_ALPHA_THRESHOLD) + ((unsigned char *)glyphs[k].image.data)[p] = 0; + else ((unsigned char *)glyphs[k].image.data)[p] = 255; } } + + k++; + glyphCounter++; } else { - // TODO: Use some fallback glyph for codepoints not found in the font + // WARNING: Glyph not found on font, optionally use a fallback glyph } } + + if (glyphCounter < codepointCount) TRACELOG(LOG_WARNING, "FONT: Requested codepoints glyphs found: [%i/%i]", k, codepointCount); } else TRACELOG(LOG_WARNING, "FONT: Failed to process TTF font data"); - if (genFontChars) RL_FREE(codepoints); + if (genFontChars) RL_FREE(requiredCodepoints); } #endif - return chars; + *glyphCount = glyphCounter; + return glyphs; } // Generate image font atlas using chars info @@ -1239,7 +1269,7 @@ void DrawTextCodepoint(Font font, int codepoint, Vector2 position, float fontSiz (font.recs[index].height + 2.0f*font.glyphPadding)*scaleFactor }; // Character source rectangle from font texture atlas - // NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects + // NOTE: We consider glyphs padding when drawing, it could be required for outline/glow shader effects Rectangle srcRec = { font.recs[index].x - (float)font.glyphPadding, font.recs[index].y - (float)font.glyphPadding, font.recs[index].width + 2.0f*font.glyphPadding, font.recs[index].height + 2.0f*font.glyphPadding }; @@ -1292,7 +1322,7 @@ int MeasureText(const char *text, int fontSize) // Check if default font has been loaded if (GetFontDefault().texture.id != 0) { - int defaultFontSize = 10; // Default Font chars height in pixel + int defaultFontSize = 10; // Default Font glyphs height in pixel if (fontSize < defaultFontSize) fontSize = defaultFontSize; int spacing = fontSize/defaultFontSize; @@ -1920,10 +1950,11 @@ char *LoadUTF8(const int *codepoints, int length) size += bytes; } - // Resize memory to text length + string NULL terminator - void *ptr = RL_REALLOC(text, size + 1); - - if (ptr != NULL) text = (char *)ptr; + // Create second buffer and copy data manually to it + char *temp = (char *)RL_CALLOC(size + 1, 1); + memcpy(temp, text, size); + RL_FREE(text); + text = temp; return text; } @@ -1951,8 +1982,11 @@ int *LoadCodepoints(const char *text, int *count) i += codepointSize; } - // Re-allocate buffer to the actual number of codepoints loaded - codepoints = (int *)RL_REALLOC(codepoints, codepointCount*sizeof(int)); + // Create second buffer and copy data manually to it + int *temp = (int *)RL_CALLOC(codepointCount, sizeof(int)); + for (int i = 0; i < codepointCount; i++) temp[i] = codepoints[i]; + RL_FREE(codepoints); + codepoints = temp; *count = codepointCount; @@ -2193,7 +2227,7 @@ int GetCodepointPrevious(const char *text, int *codepointSize) } //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- #if defined(SUPPORT_FILEFORMAT_FNT) || defined(SUPPORT_FILEFORMAT_BDF) // Read a line from memory @@ -2376,11 +2410,9 @@ static Font LoadBMFont(const char *fileName) return font; } - #endif #if defined(SUPPORT_FILEFORMAT_BDF) - // Convert hexadecimal to decimal (single digit) static unsigned char HexToInt(char hex) { @@ -2392,7 +2424,7 @@ static unsigned char HexToInt(char hex) // Load font data for further use // NOTE: Requires BDF font memory data -static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, int *codepoints, int codepointCount, int *outFontSize) +static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, const int *codepoints, int codepointCount, int *outFontSize) { #define MAX_BUFFER_SIZE 256 @@ -2426,7 +2458,9 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i int charBByoff0 = 0; // Character bounding box Y0 offset int charDWidthX = 0; // Character advance X int charDWidthY = 0; // Character advance Y (unused) - GlyphInfo *charGlyphInfo = NULL; // Pointer to output glyph info (NULL if not set) + + GlyphInfo *glyphs = NULL; // Pointer to output glyph info (NULL if not set) + int *requiredCodepoints = codepoints; if (fileData == NULL) return glyphs; @@ -2435,10 +2469,10 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i // Fill fontChars in case not provided externally // NOTE: By default we fill glyphCount consecutively, starting at 32 (Space) - if (codepoints == NULL) + if (requiredCodepoints == NULL) { - codepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); - for (int i = 0; i < codepointCount; i++) codepoints[i] = i + 32; + requiredCodepoints = (int *)RL_MALLOC(codepointCount*sizeof(int)); + for (int i = 0; i < codepointCount; i++) requiredCodepoints[i] = i + 32; genFontChars = true; } @@ -2464,11 +2498,11 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i if (charBitmapStarted) { - if (charGlyphInfo != NULL) + if (glyphs != NULL) { int pixelY = charBitmapNextRow++; - if (pixelY >= charGlyphInfo->image.height) break; + if (pixelY >= glyphs->image.height) break; for (int x = 0; x < readBytes; x++) { @@ -2478,9 +2512,9 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i { int pixelX = ((x*4) + bitX); - if (pixelX >= charGlyphInfo->image.width) break; + if (pixelX >= glyphs->image.width) break; - if ((byte & (8 >> bitX)) > 0) ((unsigned char *)charGlyphInfo->image.data)[(pixelY*charGlyphInfo->image.width) + pixelX] = 255; + if ((byte & (8 >> bitX)) > 0) ((unsigned char *)glyphs->image.data)[(pixelY*glyphs->image.width) + pixelX] = 255; } } } @@ -2512,30 +2546,30 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i if (strstr(buffer, "BITMAP") != NULL) { // Search for glyph index in codepoints - charGlyphInfo = NULL; + glyphs = NULL; for (int codepointIndex = 0; codepointIndex < codepointCount; codepointIndex++) { if (codepoints[codepointIndex] == charEncoding) { - charGlyphInfo = &glyphs[codepointIndex]; + glyphs = &glyphs[codepointIndex]; break; } } // Init glyph info - if (charGlyphInfo != NULL) + if (glyphs != NULL) { - charGlyphInfo->value = charEncoding; - charGlyphInfo->offsetX = charBBxoff0 + fontBByoff0; - charGlyphInfo->offsetY = fontBBh - (charBBh + charBByoff0 + fontBByoff0 + fontAscent); - charGlyphInfo->advanceX = charDWidthX; + glyphs->value = charEncoding; + glyphs->offsetX = charBBxoff0 + fontBByoff0; + glyphs->offsetY = fontBBh - (charBBh + charBByoff0 + fontBByoff0 + fontAscent); + glyphs->advanceX = charDWidthX; - charGlyphInfo->image.data = RL_CALLOC(charBBw*charBBh, 1); - charGlyphInfo->image.width = charBBw; - charGlyphInfo->image.height = charBBh; - charGlyphInfo->image.mipmaps = 1; - charGlyphInfo->image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; + glyphs->image.data = RL_CALLOC(charBBw*charBBh, 1); + glyphs->image.width = charBBw; + glyphs->image.height = charBBh; + glyphs->image.mipmaps = 1; + glyphs->image.format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE; } charBitmapStarted = true; @@ -2586,14 +2620,14 @@ static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, i { charStarted = true; charEncoding = -1; - charGlyphInfo = NULL; + glyphs = NULL; charBBw = 0; charBBh = 0; charBBxoff0 = 0; charBByoff0 = 0; charDWidthX = 0; charDWidthY = 0; - charGlyphInfo = NULL; + glyphs = NULL; charBitmapStarted = false; charBitmapNextRow = 0; continue; diff --git a/src/rtextures.c b/src/rtextures.c index 624cf574a..18ee1af99 100644 --- a/src/rtextures.c +++ b/src/rtextures.c @@ -258,7 +258,7 @@ extern void LoadFontDefault(void); // [Module: text] Loads default font, required by ImageDrawText() //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- static float HalfToFloat(unsigned short x); static unsigned short FloatToHalf(float x); @@ -267,7 +267,6 @@ static Vector4 *LoadImageDataNormalized(Image image); // Load pixel data f //---------------------------------------------------------------------------------- // Module Functions Definition //---------------------------------------------------------------------------------- - // Load image from file into CPU memory (RAM) Image LoadImage(const char *fileName) { @@ -422,7 +421,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i { Image image = { 0 }; - // Security check for input data + // Security checks for input data if ((fileData == NULL) || (dataSize == 0)) { TRACELOG(LOG_WARNING, "IMAGE: Invalid file data"); @@ -650,16 +649,15 @@ bool ExportImage(Image image, const char *fileName) allocatedData = true; } + if (false) { } // Required to attach following 'else' cases #if defined(SUPPORT_FILEFORMAT_PNG) - if (IsFileExtension(fileName, ".png")) + else if (IsFileExtension(fileName, ".png")) { int dataSize = 0; unsigned char *fileData = stbi_write_png_to_mem((const unsigned char *)imgData, image.width*channels, image.width, image.height, channels, &dataSize); result = SaveFileData(fileName, fileData, dataSize); RL_FREE(fileData); } -#else - if (false) { } #endif #if defined(SUPPORT_FILEFORMAT_BMP) else if (IsFileExtension(fileName, ".bmp")) result = stbi_write_bmp(fileName, image.width, image.height, channels, imgData); @@ -703,7 +701,8 @@ bool ExportImage(Image image, const char *fileName) // NOTE: It's up to the user to track image parameters result = SaveFileData(fileName, image.data, GetPixelDataSize(image.width, image.height, image.format)); } - + else TRACELOG(LOG_WARNING, "IMAGE: Export image format requested not supported"); + if (allocatedData) RL_FREE(imgData); #endif // SUPPORT_IMAGE_EXPORT @@ -2400,10 +2399,11 @@ void ImageMipmaps(Image *image) if (image->mipmaps < mipCount) { - void *temp = RL_REALLOC(image->data, mipSize); - - if (temp != NULL) image->data = temp; // Assign new pointer (new size) to store mipmaps data - else TRACELOG(LOG_WARNING, "IMAGE: Mipmaps required memory could not be allocated"); + // Create second buffer and copy data manually to it + void *temp = RL_CALLOC(mipSize, 1); + memcpy(temp, image->data, GetPixelDataSize(image->width, image->height, image->format)); + RL_FREE(image->data); + image->data = temp; // Pointer to allocated memory point where store next mipmap level data unsigned char *nextmip = image->data; @@ -2429,9 +2429,7 @@ void ImageMipmaps(Image *image) if (i < image->mipmaps) continue; TRACELOGD("IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip); - ImageResize(&imCopy, mipWidth, mipHeight); // Uses internally Mitchell cubic downscale filter - memcpy(nextmip, imCopy.data, mipSize); } @@ -5407,7 +5405,7 @@ int GetPixelDataSize(int width, int height, int format) } //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- // Convert half-float (stored as unsigned short) to float // REF: https://stackoverflow.com/questions/1659440/32-bit-to-16-bit-floating-point-conversion/60047308#60047308 diff --git a/src/utils.c b/src/utils.c index 26e7a1bab..310ebfc78 100644 --- a/src/utils.c +++ b/src/utils.c @@ -82,7 +82,7 @@ static const char *internalDataPath = NULL; // Android internal data pat #endif //---------------------------------------------------------------------------------- -// Module specific Functions Declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- #if defined(PLATFORM_ANDROID) FILE *funopen(const void *cookie, int (*readfn)(void *, char *, int), int (*writefn)(void *, const char *, int), @@ -482,7 +482,7 @@ FILE *android_fopen(const char *fileName, const char *mode) #endif // PLATFORM_ANDROID //---------------------------------------------------------------------------------- -// Module specific Functions Definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- #if defined(PLATFORM_ANDROID) static int android_read(void *cookie, char *data, int dataSize) diff --git a/tools/parser/output/raylib_api.json b/tools/parser/output/raylib_api.json index 3617d6392..4ce190714 100644 --- a/tools/parser/output/raylib_api.json +++ b/tools/parser/output/raylib_api.json @@ -753,7 +753,7 @@ { "type": "float", "name": "fovy", - "description": "Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic" + "description": "Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic" }, { "type": "int", @@ -9129,7 +9129,7 @@ "name": "fontSize" }, { - "type": "int *", + "type": "const int *", "name": "codepoints" }, { @@ -9139,6 +9139,10 @@ { "type": "int", "name": "type" + }, + { + "type": "int *", + "name": "glyphCount" } ] }, diff --git a/tools/parser/output/raylib_api.lua b/tools/parser/output/raylib_api.lua index 00abc0c77..e52fda62d 100644 --- a/tools/parser/output/raylib_api.lua +++ b/tools/parser/output/raylib_api.lua @@ -753,7 +753,7 @@ return { { type = "float", name = "fovy", - description = "Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic" + description = "Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic" }, { type = "int", @@ -6593,9 +6593,10 @@ return { {type = "const unsigned char *", name = "fileData"}, {type = "int", name = "dataSize"}, {type = "int", name = "fontSize"}, - {type = "int *", name = "codepoints"}, + {type = "const int *", name = "codepoints"}, {type = "int", name = "codepointCount"}, - {type = "int", name = "type"} + {type = "int", name = "type"}, + {type = "int *", name = "glyphCount"} } }, { diff --git a/tools/parser/output/raylib_api.txt b/tools/parser/output/raylib_api.txt index 12af97c08..b164b7e88 100644 --- a/tools/parser/output/raylib_api.txt +++ b/tools/parser/output/raylib_api.txt @@ -394,7 +394,7 @@ Struct 13: Camera3D (5 fields) Field[1]: Vector3 position // Camera position Field[2]: Vector3 target // Camera target it looks-at Field[3]: Vector3 up // Camera up vector (rotation over its axis) - Field[4]: float fovy // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic + Field[4]: float fovy // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane height in world units in orthographic Field[5]: int projection // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC Struct 14: Camera2D (4 fields) Name: Camera2D @@ -3492,16 +3492,17 @@ Function 398: IsFontValid() (1 input parameters) Return type: bool Description: Check if a font is valid (font data loaded, WARNING: GPU texture not checked) Param[1]: font (type: Font) -Function 399: LoadFontData() (6 input parameters) +Function 399: LoadFontData() (7 input parameters) Name: LoadFontData Return type: GlyphInfo * Description: Load font data for further use Param[1]: fileData (type: const unsigned char *) Param[2]: dataSize (type: int) Param[3]: fontSize (type: int) - Param[4]: codepoints (type: int *) + Param[4]: codepoints (type: const int *) Param[5]: codepointCount (type: int) Param[6]: type (type: int) + Param[7]: glyphCount (type: int *) Function 400: GenImageFontAtlas() (6 input parameters) Name: GenImageFontAtlas Return type: Image diff --git a/tools/parser/output/raylib_api.xml b/tools/parser/output/raylib_api.xml index 0a053abc6..43835334d 100644 --- a/tools/parser/output/raylib_api.xml +++ b/tools/parser/output/raylib_api.xml @@ -151,7 +151,7 @@ - + @@ -2305,13 +2305,14 @@ - + - + + diff --git a/tools/rexm/examples_report.md b/tools/rexm/examples_report.md index 1c08d9270..a4bcef40c 100644 --- a/tools/rexm/examples_report.md +++ b/tools/rexm/examples_report.md @@ -36,7 +36,7 @@ Example elements validated: | core_3d_camera_free | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_3d_camera_first_person | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_3d_camera_split_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | -| core_3d_fps_controller | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| core_3d_camera_fps | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_3d_picking | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_world_screen | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | core_custom_logging | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -113,6 +113,7 @@ Example elements validated: | text_writing_anim | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_rectangle_bounds | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_unicode | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_unicode_ranges | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_draw_3d | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_codepoints_loading | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_animation | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -181,4 +182,4 @@ Example elements validated: | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | raymath_vector_angle | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | -| text_unicode_ranges | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_unicode_ranges | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/examples_report_issues.md b/tools/rexm/examples_report_issues.md index 12e8c656e..9f82a6dfa 100644 --- a/tools/rexm/examples_report_issues.md +++ b/tools/rexm/examples_report_issues.md @@ -26,6 +26,7 @@ Example elements validated: | core_high_dpi | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | shapes_digital_clock | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_font_sdf | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | +| text_unicode_ranges | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_draw_3d | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | text_codepoints_loading | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | models_loading_m3d | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | @@ -37,4 +38,3 @@ Example elements validated: | raylib_opengl_interop | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | | embedded_files_loading | ✔ | ❌ | ❌ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | raymath_vector_angle | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ | -| text_unicode_ranges | ✔ | ✔ | ✔ | ❌ | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | diff --git a/tools/rexm/rexm.c b/tools/rexm/rexm.c index 9ab4950c8..db1e0fbf7 100644 --- a/tools/rexm/rexm.c +++ b/tools/rexm/rexm.c @@ -129,7 +129,7 @@ static const char *exCollectionFilePath = NULL; // Env: REXM_EXAMPLES_COLLECTION static const char *exVSProjectSolutionFile = NULL; // Env REXM_EXAMPLES_VS2022_SLN_FILE //---------------------------------------------------------------------------------- -// Module specific functions declaration +// Module Internal Functions Declaration //---------------------------------------------------------------------------------- static int FileTextFind(const char *fileName, const char *find); static int FileTextReplace(const char *fileName, const char *find, const char *replace); @@ -181,6 +181,8 @@ static void UpdateWebMetadata(const char *exHtmlPath, const char *exFilePath); //------------------------------------------------------------------------------------ int main(int argc, char *argv[]) { + SetTraceLogLevel(LOG_NONE); + // Path values can be configured with environment variables exBasePath = getenv("REXM_EXAMPLES_BASE_PATH"); exWebPath = getenv("REXM_EXAMPLES_WEB_PATH"); @@ -370,15 +372,13 @@ int main(int argc, char *argv[]) { // Verify example exists in collection to be removed char *exColInfo = LoadFileText(exCollectionFilePath); - if ((TextFindIndex(exColInfo, argv[2]) != -1) && // Example in the collection - (TextFindIndex(exName, "_") != -1)) // Valid example name + if (TextFindIndex(exColInfo, argv[2]) != -1) // Example in the collection { - strcpy(exName, argv[2]); // Register example name for removal strncpy(exCategory, exName, TextFindIndex(exName, "_")); opCode = OP_BUILD; } - else LOG("WARNING: REMOVE: Example not available in the collection\n"); + else LOG("WARNING: BUILD: Example not available in the collection\n"); UnloadFileText(exColInfo); } } @@ -1257,9 +1257,9 @@ int main(int argc, char *argv[]) printf("////////////////////////////////////////////////////////////////////////////////////////////\n\n"); printf("USAGE:\n\n"); - printf(" > rexm []\n"); + printf(" > rexm []\n\n"); - printf("\COMMANDS:\n\n"); + printf("COMMANDS:\n\n"); printf(" help : Provides command-line usage information\n"); printf(" create : Creates an empty example, from internal template\n"); printf(" add : Add existing example, category extracted from name\n"); @@ -1283,9 +1283,8 @@ int main(int argc, char *argv[]) } //---------------------------------------------------------------------------------- -// Module specific functions definition +// Module Internal Functions Definition //---------------------------------------------------------------------------------- - // Update required files from examples collection static int UpdateRequiredFiles(void) { @@ -1772,7 +1771,7 @@ static int FileMove(const char *srcPath, const char *dstPath) // Get example info from example file header // NOTE: Expecting the example to follow raylib_example_template.c -rlExampleInfo *LoadExampleInfo(const char *exFileName) +static rlExampleInfo *LoadExampleInfo(const char *exFileName) { rlExampleInfo *exInfo = (rlExampleInfo *)RL_CALLOC(1, sizeof(rlExampleInfo));