From e7fdf8a13d88520379620f45ff43550bd75a546f Mon Sep 17 00:00:00 2001 From: Tyler Jessilynn Bezera Date: Sat, 22 Feb 2020 01:17:30 -0800 Subject: [PATCH 01/37] Expand GLTF Model support (#1108) * Update GLTF support to include loading color for albdeo (saved in the color value of the materialmap), support occlussion and emmission maps.. as well as some quality of life updates. * clean up to use single image --- src/models.c | 87 +++++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 39 deletions(-) diff --git a/src/models.c b/src/models.c index 1a3ae3ed7..6d95441fe 100644 --- a/src/models.c +++ b/src/models.c @@ -3377,9 +3377,9 @@ static unsigned char *DecodeBase64(char *input, int *size) } // Load texture from cgltf_image -static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath, Color tint) +static Image LoadImageFromCgltfImage(cgltf_image *image, const char *texPath, Color tint) { - Texture texture = { 0 }; + Image rimage = { 0 }; if (image->uri) { @@ -3406,22 +3406,18 @@ static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath int w, h; unsigned char *raw = stbi_load_from_memory(data, size, &w, &h, NULL, 4); - Image rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8); + rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8); // TODO: Tint shouldn't be applied here! ImageColorTint(&rimage, tint); - texture = LoadTextureFromImage(rimage); - UnloadImage(rimage); } } else { - Image rimage = LoadImage(TextFormat("%s/%s", texPath, image->uri)); + rimage = LoadImage(TextFormat("%s/%s", texPath, image->uri)); // TODO: Tint shouldn't be applied here! ImageColorTint(&rimage, tint); - texture = LoadTextureFromImage(rimage); - UnloadImage(rimage); } } else if (image->buffer_view) @@ -3440,41 +3436,36 @@ static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath unsigned char *raw = stbi_load_from_memory(data, image->buffer_view->size, &w, &h, NULL, 4); free(data); - Image rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8); + rimage = LoadImagePro(raw, w, h, UNCOMPRESSED_R8G8B8A8); free(raw); // TODO: Tint shouldn't be applied here! ImageColorTint(&rimage, tint); - texture = LoadTextureFromImage(rimage); - UnloadImage(rimage); } else { - Image rimage = LoadImageEx(&tint, 1, 1); - texture = LoadTextureFromImage(rimage); - UnloadImage(rimage); + rimage = LoadImageEx(&tint, 1, 1); } - return texture; + return rimage; } -// Load glTF mesh data +// LoadGLTF loads in model data from given filename, supporting both .gltf and .glb static Model LoadGLTF(const char *fileName) { /*********************************************************************************** - Function implemented by Wilhem Barbier (@wbrbr) + Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend) Features: - Supports .gltf and .glb files - Supports embedded (base64) or external textures - - Loads the albedo/diffuse texture (other maps could be added) + - Loads all raylib supported material textures, values and colors - Supports multiple mesh per model and multiple primitives per model Some restrictions (not exhaustive): - Triangle-only meshes - Not supported node hierarchies or transforms - - Only loads the diffuse texture... but not too hard to support other maps (normal, roughness/metalness...) - Only supports unsigned short indices (no byte/unsigned int) - Only supports float for texture coordinates (no byte/unsigned short) @@ -3547,44 +3538,62 @@ static Model LoadGLTF(const char *fileName) //Ensure material follows raylib support for PBR (metallic/roughness flow) if (data->materials[i].has_pbr_metallic_roughness) { - float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor; - float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor; + tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0] * 255); + tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1] * 255); + tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2] * 255); + tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3] * 255); - // NOTE: Material name not used for the moment - //if (model.materials[i].name && data->materials[i].name) strcpy(model.materials[i].name, data->materials[i].name); - - // TODO: REview: shouldn't these be *255 ??? - tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0]*255); - tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1]*255); - tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2]*255); - tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3]*255); - - model.materials[i].maps[MAP_ROUGHNESS].color = tint; + model.materials[i].maps[MAP_ALBEDO].color = tint; if (data->materials[i].pbr_metallic_roughness.base_color_texture.texture) { - model.materials[i].maps[MAP_ALBEDO].texture = LoadTextureFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint); + Image albedo = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint); + model.materials[i].maps[MAP_ALBEDO].texture = LoadTextureFromImage(albedo); + UnloadImage(albedo); } - // NOTE: Tint isn't need for other textures.. pass null or clear? - // Just set as white, multiplying by white has no effect + //Set tint to white after it's been used by Albedo tint = WHITE; if (data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture) { - model.materials[i].maps[MAP_ROUGHNESS].texture = LoadTextureFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint); + Image metallicRoughness = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint); + model.materials[i].maps[MAP_ROUGHNESS].texture = LoadTextureFromImage(metallicRoughness); + + float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor; + model.materials[i].maps[MAP_ROUGHNESS].value = roughness; + + float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor; + model.materials[i].maps[MAP_METALNESS].value = metallic; + + UnloadImage(metallicRoughness); } - model.materials[i].maps[MAP_ROUGHNESS].value = roughness; - model.materials[i].maps[MAP_METALNESS].value = metallic; + + if (data->materials[i].normal_texture.texture) { - model.materials[i].maps[MAP_NORMAL].texture = LoadTextureFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint); + Image normalImage = LoadImageFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint); + model.materials[i].maps[MAP_NORMAL].texture = LoadTextureFromImage(normalImage); + UnloadImage(normalImage); } if (data->materials[i].occlusion_texture.texture) { - model.materials[i].maps[MAP_OCCLUSION].texture = LoadTextureFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint); + Image occulsionImage = LoadImageFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint); + model.materials[i].maps[MAP_OCCLUSION].texture = LoadTextureFromImage(occulsionImage); + UnloadImage(occulsionImage); + } + + if (data->materials[i].emissive_texture.texture) + { + Image emissiveImage = LoadImageFromCgltfImage(data->materials[i].emissive_texture.texture->image, texPath, tint); + model.materials[i].maps[MAP_EMISSION].texture = LoadTextureFromImage(emissiveImage); + tint.r = (unsigned char)(data->materials[i].emissive_factor[0] * 255); + tint.g = (unsigned char)(data->materials[i].emissive_factor[1] * 255); + tint.b = (unsigned char)(data->materials[i].emissive_factor[2] * 255); + model.materials[i].maps[MAP_EMISSION].color = tint; + UnloadImage(emissiveImage); } } } From 81881a120c7cfafa3448132cb63c71793920e076 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Feb 2020 10:36:20 +0100 Subject: [PATCH 02/37] Comment tweak --- src/shell.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/shell.html b/src/shell.html index 7db891bef..507b35acf 100644 --- a/src/shell.html +++ b/src/shell.html @@ -241,8 +241,8 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB canvas: (function() { var canvas = document.querySelector('#canvas'); - // As a default initial behavior, pop up an alert when webgl context is lost. To make your - // application robust, you may want to override this behavior before shipping! + // As a default initial behavior, pop up an alert when webgl context is lost. + // To make your application robust, you may want to override this behavior before shipping! // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2 canvas.addEventListener("webglcontextlost", function(e) { alert('WebGL context lost. You will need to reload the page.'); e.preventDefault(); }, false); From d2aeafcf1ef3e6cace8a15d8ff0f8c71697d8714 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Feb 2020 10:36:34 +0100 Subject: [PATCH 03/37] Update Makefile --- src/Makefile | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Makefile b/src/Makefile index e7086e55c..3a7907895 100644 --- a/src/Makefile +++ b/src/Makefile @@ -291,9 +291,16 @@ endif ifeq ($(RAYLIB_BUILD_MODE),DEBUG) CFLAGS += -g + ifeq ($(PLATFORM),PLATFORM_WEB) + CFLAGS += -s ASSERTIONS=1 --profiling + endif endif ifeq ($(RAYLIB_BUILD_MODE),RELEASE) - CFLAGS += -O1 + ifeq ($(PLATFORM),PLATFORM_WEB) + CFLAGS += -Os + else + CFLAGS += -s -O1 + endif endif # Additional flags for compiler (if desired) @@ -311,18 +318,12 @@ ifeq ($(PLATFORM),PLATFORM_WEB) # -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL! # -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) # -s USE_PTHREADS=1 # multithreading support - # -s WASM=0 # disable Web Assembly, emitted by default - # -s EMTERPRETIFY=1 # enable emscripten code interpreter (very slow) - # -s EMTERPRETIFY_ASYNC=1 # support synchronous loops by emterpreter # -s FORCE_FILESYSTEM=1 # force filesystem to load/save files data # -s ASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off) # --profiling # include information for code profiling # --memory-init-file 0 # to avoid an external memory initialization code file (.mem) # --preload-file resources # specify a resources folder for data compilation CFLAGS += -s USE_GLFW=3 - ifeq ($(RAYLIB_BUILD_MODE),DEBUG) - CFLAGS += -s ASSERTIONS=1 --profiling - endif endif ifeq ($(PLATFORM),PLATFORM_ANDROID) # Compiler flags for arquitecture From 0b8aded39945081f70682f943912a631fa407657 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Feb 2020 10:37:43 +0100 Subject: [PATCH 04/37] Support ToggleFullscreen() on web --- src/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/core.c b/src/core.c index 814ed9f5f..0beec99ce 100644 --- a/src/core.c +++ b/src/core.c @@ -867,9 +867,9 @@ bool IsWindowHidden(void) // Toggle fullscreen mode (only PLATFORM_DESKTOP) void ToggleFullscreen(void) { -#if defined(PLATFORM_DESKTOP) CORE.Window.fullscreen = !CORE.Window.fullscreen; // Toggle fullscreen flag +#if defined(PLATFORM_DESKTOP) // NOTE: glfwSetWindowMonitor() doesn't work properly (bugs) if (CORE.Window.fullscreen) { @@ -893,7 +893,10 @@ void ToggleFullscreen(void) } else glfwSetWindowMonitor(CORE.Window.handle, NULL, CORE.Window.position.x, CORE.Window.position.y, CORE.Window.screen.width, CORE.Window.screen.height, GLFW_DONT_CARE); #endif - +#if defined(PLATFORM_WEB) + if (CORE.Window.fullscreen) EM_ASM(Module.requestFullscreen(false, false);); + else EM_ASM(document.exitFullscreen();); +#endif #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) TRACELOG(LOG_WARNING, "Could not toggle to windowed mode"); #endif From 30f3e49f3dc38465c25052f987a81184901acb7b Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Feb 2020 10:38:32 +0100 Subject: [PATCH 05/37] Improve inputs on Android --- src/core.c | 126 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 92 insertions(+), 34 deletions(-) diff --git a/src/core.c b/src/core.c index 0beec99ce..111b2be6d 100644 --- a/src/core.c +++ b/src/core.c @@ -2514,7 +2514,11 @@ bool IsMouseButtonReleased(int button) { bool released = false; -#if !defined(PLATFORM_ANDROID) +#if defined(PLATFORM_ANDROID) + # if defined(SUPPORT_GESTURES_SYSTEM) + released = GetGestureDetected() == GESTURE_TAP; + # endif +#else if ((CORE.Input.Mouse.currentButtonState[button] != CORE.Input.Mouse.previousButtonState[button]) && (GetMouseButtonStatus(button) == 0)) released = true; #endif @@ -4233,37 +4237,84 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) { // If additional inputs are required check: // https://developer.android.com/ndk/reference/group/input + // https://developer.android.com/training/game-controllers/controller-input int type = AInputEvent_getType(event); + int source = AInputEvent_getSource(event); if (type == AINPUT_EVENT_TYPE_MOTION) { - // Get first touch position - CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0); - CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0); - - // Get second touch position - CORE.Input.Touch.position[1].x = AMotionEvent_getX(event, 1); - CORE.Input.Touch.position[1].y = AMotionEvent_getY(event, 1); - - // Useful functions for gamepad inputs: - //AMotionEvent_getAction() - //AMotionEvent_getAxisValue() - //AMotionEvent_getButtonState() - - // Gamepad dpad button presses capturing - // TODO: That's weird, key input (or button) - // shouldn't come as a TYPE_MOTION event... - int32_t keycode = AKeyEvent_getKeyCode(event); - if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) + if ((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK || (source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD) { - CORE.Input.Keyboard.currentKeyState[keycode] = 1; // Key down + // Get first touch position + CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0); + CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0); - CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; - CORE.Input.Keyboard.keyPressedQueueCount++; + // Get second touch position + CORE.Input.Touch.position[1].x = AMotionEvent_getX(event, 1); + CORE.Input.Touch.position[1].y = AMotionEvent_getY(event, 1); + + int32_t keycode = AKeyEvent_getKeyCode(event); + if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN) + { + CORE.Input.Keyboard.currentKeyState[keycode] = 1; // Key down + + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode; + CORE.Input.Keyboard.keyPressedQueueCount++; + } + else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up + + // Stop processing gamepad buttons + return 1; } - else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up + int32_t action = AMotionEvent_getAction(event); + unsigned int flags = action & AMOTION_EVENT_ACTION_MASK; + + // Simple touch position + if (flags == AMOTION_EVENT_ACTION_DOWN) + { + // Get first touch position + CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0); + CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0); + } + +#if defined(SUPPORT_GESTURES_SYSTEM) + GestureEvent gestureEvent; + + // Register touch actions + if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.touchAction = TOUCH_DOWN; + else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.touchAction = TOUCH_UP; + else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.touchAction = TOUCH_MOVE; + + // Register touch points count + // NOTE: Documentation says pointerCount is Always >= 1, + // but in practice it can be 0 or over a million + gestureEvent.pointCount = AMotionEvent_getPointerCount(event); + + // Only enable gestures for 1-3 touch points + if ((gestureEvent.pointCount > 0) && (gestureEvent.pointCount < 4)) + { + // Register touch points id + // NOTE: Only two points registered + gestureEvent.pointerId[0] = AMotionEvent_getPointerId(event, 0); + gestureEvent.pointerId[1] = AMotionEvent_getPointerId(event, 1); + + // Register touch points position + gestureEvent.position[0] = (Vector2){ AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) }; + gestureEvent.position[1] = (Vector2){ AMotionEvent_getX(event, 1), AMotionEvent_getY(event, 1) }; + + // Normalize gestureEvent.position[x] for screenWidth and screenHeight + gestureEvent.position[0].x /= (float)GetScreenWidth(); + gestureEvent.position[0].y /= (float)GetScreenHeight(); + + gestureEvent.position[1].x /= (float)GetScreenWidth(); + gestureEvent.position[1].y /= (float)GetScreenHeight(); + + // Gesture data is sent to gestures system for processing + ProcessGestureEvent(gestureEvent); + } +#endif } else if (type == AINPUT_EVENT_TYPE_KEY) { @@ -4300,11 +4351,29 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) // Set default OS behaviour return 0; } + + return 0; } int32_t action = AMotionEvent_getAction(event); unsigned int flags = action & AMOTION_EVENT_ACTION_MASK; + // Support only simple touch position + if (flags == AMOTION_EVENT_ACTION_DOWN) + { + // Get first touch position + CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0); + CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0); + } + else if (flags == AMOTION_EVENT_ACTION_UP) + { + // Get first touch position + CORE.Input.Touch.position[0].x = 0; + CORE.Input.Touch.position[0].y = 0; + } + else // TODO:Not sure what else should be handled + return 0; + #if defined(SUPPORT_GESTURES_SYSTEM) GestureEvent gestureEvent = { 0 }; @@ -4340,17 +4409,6 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) // Gesture data is sent to gestures system for processing ProcessGestureEvent(gestureEvent); } -#else - // Support only simple touch position - if (flags == AMOTION_EVENT_ACTION_DOWN) - { - // Get first touch position - CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0); - CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0); - - CORE.Input.Touch.position[0].x /= (float)GetScreenWidth(); - CORE.Input.Touch.position[0].y /= (float)GetScreenHeight(); - } #endif return 0; From 310fd9b1471a94d83764caece418cbe451ba2af1 Mon Sep 17 00:00:00 2001 From: Ray Date: Sat, 22 Feb 2020 17:21:10 +0100 Subject: [PATCH 06/37] Update to latest emscripten toolchain Corrected issue on web compilation --- src/Makefile | 4 ++-- src/core.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Makefile b/src/Makefile index 3a7907895..1d5bbb83c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -150,7 +150,7 @@ ifeq ($(PLATFORM),PLATFORM_WEB) EMSDK_PATH ?= C:/emsdk EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten CLANG_PATH = $(EMSDK_PATH)/upstream/bin - PYTHON_PATH = $(EMSDK_PATH)/python/2.7.13.1_64bit/python-2.7.13.amd64 + PYTHON_PATH = $(EMSDK_PATH)/python/3.7.4_64bit NODE_PATH = $(EMSDK_PATH)/node/12.9.1_64bit/bin export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH);C:\raylib\MinGW\bin:$$(PATH) endif @@ -478,7 +478,7 @@ endif raylib: $(OBJS) ifeq ($(PLATFORM),PLATFORM_WEB) # Compile raylib for web. - emcc -O1 $(OBJS) -o $(RAYLIB_RELEASE_PATH)/libraylib.bc + $(CC) -O1 $(OBJS) -o $(RAYLIB_RELEASE_PATH)/libraylib.bc @echo "raylib library generated (libraylib.bc)!" else ifeq ($(RAYLIB_LIBTYPE),SHARED) diff --git a/src/core.c b/src/core.c index 111b2be6d..5763e1489 100644 --- a/src/core.c +++ b/src/core.c @@ -703,7 +703,7 @@ void InitWindow(int width, int height, const char *title) #endif #if defined(PLATFORM_WEB) - emscripten_set_fullscreenchange_callback(0, 0, 1, EmscriptenFullscreenChangeCallback); + emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback); // Support keyboard events emscripten_set_keypress_callback("#canvas", NULL, 1, EmscriptenKeyboardCallback); From a77273d8d80a113963a56076497c1c80f5b5e229 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 24 Feb 2020 11:15:02 +0100 Subject: [PATCH 07/37] Make sure current text buffer is empty #1109 --- src/text.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/text.c b/src/text.c index d2562179b..08326cde0 100644 --- a/src/text.c +++ b/src/text.c @@ -1149,6 +1149,7 @@ const char *TextFormat(const char *text, ...) static int index = 0; char *currentBuffer = buffers[index]; + memset(currentBuffer, 0, MAX_TEXT_BUFFER_LENGTH); // Clear buffer before using va_list args; va_start(args, text); From 113a580021dc8f9d71c61804e5b8e746369e7626 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 24 Feb 2020 12:05:54 +0100 Subject: [PATCH 08/37] [rlgl] LoadText() variable scope improvement --- src/rlgl.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index 65117120a..3bbf7f001 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3001,12 +3001,11 @@ Shader GetShaderDefault(void) // NOTE: text chars array should be freed manually char *LoadText(const char *fileName) { - FILE *textFile = NULL; char *text = NULL; if (fileName != NULL) { - textFile = fopen(fileName,"rt"); + FILE *textFile = fopen(fileName, "rt"); if (textFile != NULL) { From 32e374d9417ff91fc0c6639d4f6e4db02c9cfc26 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 24 Feb 2020 12:35:53 +0100 Subject: [PATCH 09/37] [core] SetWindowSize() try to support PLATFORM_WEB -WIP- --- src/core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/core.c b/src/core.c index 5763e1489..559565dd3 100644 --- a/src/core.c +++ b/src/core.c @@ -974,6 +974,14 @@ void SetWindowSize(int width, int height) #if defined(PLATFORM_DESKTOP) glfwSetWindowSize(CORE.Window.handle, width, height); #endif +#if defined(PLATFORM_WEB) + emscripten_set_canvas_size(width, height); // DEPRECATED! + + // TODO: Below functions should be used to replace previous one but + // they do not seem to work properly + //emscripten_set_canvas_element_size("canvas", width, height); + //emscripten_set_element_css_size("canvas", width, height); +#endif } // Show the window From 9b5a796213bc5af02c1b842a2ad84827b301c009 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 20:20:52 +0100 Subject: [PATCH 10/37] Use float math functions --- src/raymath.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/raymath.h b/src/raymath.h index d1662507b..c2dbc61e4 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -1135,8 +1135,8 @@ RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount) else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount); else { - float halfTheta = (float) acos(cosHalfTheta); - float sinHalfTheta = (float) sqrt(1.0f - cosHalfTheta*cosHalfTheta); + float halfTheta = acosf(cosHalfTheta); + float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta); if (fabs(sinHalfTheta) < 0.001f) { @@ -1191,7 +1191,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat) if (trace > 0.0f) { - float s = (float)sqrt(trace + 1)*2.0f; + float s = sqrtf(trace + 1)*2.0f; float invS = 1.0f/s; result.w = s*0.25f; @@ -1215,7 +1215,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat) } else if (m11 > m22) { - float s = (float)sqrt(1.0f + m11 - m00 - m22)*2.0f; + float s = sqrtf(1.0f + m11 - m00 - m22)*2.0f; float invS = 1.0f/s; result.w = (mat.m8 - mat.m2)*invS; @@ -1225,7 +1225,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat) } else { - float s = (float)sqrt(1.0f + m22 - m00 - m11)*2.0f; + float s = sqrtf(1.0f + m22 - m00 - m11)*2.0f; float invS = 1.0f/s; result.w = (mat.m1 - mat.m4)*invS; @@ -1317,8 +1317,8 @@ RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle Vector3 resAxis = { 0.0f, 0.0f, 0.0f }; float resAngle = 0.0f; - resAngle = 2.0f*(float)acos(q.w); - float den = (float)sqrt(1.0f - q.w*q.w); + resAngle = 2.0f*acosf(q.w); + float den = sqrtf(1.0f - q.w*q.w); if (den > 0.0001f) { From 7849db65e09159023356161408617e5f3515e25b Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 20:23:06 +0100 Subject: [PATCH 11/37] Remove TraceLog() dependency on standalone mode --- src/rlgl.h | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/src/rlgl.h b/src/rlgl.h index 3bbf7f001..f6895f82a 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -76,15 +76,7 @@ #endif // Support TRACELOG macros - #if defined(RLGL_SUPPORT_TRACELOG) - #define TRACELOG(level, ...) TraceLog(level, __VA_ARGS__) - - #if defined(RLGL_SUPPORT_TRACELOG_DEBUG) - #define TRACELOGD(...) TraceLog(LOG_DEBUG, __VA_ARGS__) - #else - #define TRACELOGD(...) (void)0 - #endif - #else + #if !defined(TRACELOG) #define TRACELOG(level, ...) (void)0 #define TRACELOGD(...) (void)0 #endif @@ -676,10 +668,6 @@ RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data #include // OpenGL ES 2.0 extensions library #endif -#if defined(RLGL_STANDALONE) - #include // Required for: va_list, va_start(), vfprintf(), va_end() [Used in TraceLog()] -#endif - //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -4644,29 +4632,6 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight) #endif #if defined(RLGL_STANDALONE) -// Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) -void TraceLog(int msgType, const char *text, ...) -{ - va_list args; - va_start(args, text); - - switch (msgType) - { - case LOG_INFO: fprintf(stdout, "INFO: "); break; - case LOG_ERROR: fprintf(stdout, "ERROR: "); break; - case LOG_WARNING: fprintf(stdout, "WARNING: "); break; - case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break; - default: break; - } - - vfprintf(stdout, text, args); - fprintf(stdout, "\n"); - - va_end(args); - - if (msgType == LOG_ERROR) exit(1); -} - // Get pixel data size in bytes (image or texture) // NOTE: Size depends on pixel format int GetPixelDataSize(int width, int height, int format) From 0f783aab34b29656c96aa53235c54caa8b5d252f Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 20:23:36 +0100 Subject: [PATCH 12/37] Remove TraceLog() dependency on standalone mode --- src/raudio.c | 51 ++++++++++----------------------------------------- 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index 060dedc82..4e7118fdf 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -80,7 +80,7 @@ #if defined(_WIN32) // To avoid conflicting windows.h symbols with raylib, some flags are defined -// WARNING: Those flags avoid inclusion of some Win32 headers that could be required +// WARNING: Those flags avoid inclusion of some Win32 headers that could be required // by user at some point and won't be included... //------------------------------------------------------------------------------------- @@ -165,6 +165,10 @@ typedef struct tagBITMAPINFOHEADER { #if defined(RAUDIO_STANDALONE) #include // Required for: strcmp() [Used in IsFileExtension()] + + #if !defined(TRACELOG) + #define TRACELOG(level, ...) (void)0 + #endif #endif #if defined(SUPPORT_FILEFORMAT_OGG) @@ -1552,11 +1556,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, ma_uint32 subBufferSizeInFrames = (audioBuffer->sizeInFrames > 1)? audioBuffer->sizeInFrames/2 : audioBuffer->sizeInFrames; ma_uint32 currentSubBufferIndex = audioBuffer->frameCursorPos/subBufferSizeInFrames; - if (currentSubBufferIndex > 1) - { - TRACELOGD("Frame cursor position moved too far forward in audio stream"); - return 0; - } + if (currentSubBufferIndex > 1) return 0; // Another thread can update the processed state of buffers so // we just take a copy here to try and avoid potential synchronization problems @@ -1639,7 +1639,7 @@ static ma_uint32 ReadAudioBufferFramesInInternalFormat(AudioBuffer *audioBuffer, // Reads audio data from an AudioBuffer object in device format. Returned data will be in a format appropriate for mixing. static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, float *framesOut, ma_uint32 frameCount) { - // What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which + // What's going on here is that we're continuously converting data from the AudioBuffer's internal format to the mixing format, which // should be defined by the output format of the data converter. We do this until frameCount frames have been output. The important // detail to remember here is that we never, ever attempt to read more input data than is required for the specified number of output // frames. This can be achieved with ma_data_converter_get_required_input_frame_count(). @@ -1663,7 +1663,7 @@ static ma_uint32 ReadAudioBufferFramesInMixingFormat(AudioBuffer *audioBuffer, f ma_uint64 inputFramesProcessedThisIteration = ReadAudioBufferFramesInInternalFormat(audioBuffer, inputBuffer, (ma_uint32)inputFramesToProcessThisIteration); /* Safe cast. */ ma_uint64 outputFramesProcessedThisIteration = outputFramesToProcessThisIteration; ma_data_converter_process_pcm_frames(&audioBuffer->converter, inputBuffer, &inputFramesProcessedThisIteration, runningFramesOut, &outputFramesProcessedThisIteration); - + totalOutputFramesProcessed += (ma_uint32)outputFramesProcessedThisIteration; /* Safe cast. */ if (inputFramesProcessedThisIteration < inputFramesToProcessThisIteration) @@ -1704,13 +1704,7 @@ static void OnSendAudioDataToDevice(ma_device *pDevice, void *pFramesOut, const while (1) { - if (framesRead > frameCount) - { - TRACELOGD("Mixed too many frames from audio buffer"); - break; - } - - if (framesRead == frameCount) break; + if (framesRead >= frameCount) break; // Just read as much data as we can from the stream ma_uint32 framesToRead = (frameCount - framesRead); @@ -2037,9 +2031,7 @@ static Wave LoadOGG(const char *fileName) wave.data = (short *)RL_MALLOC(wave.sampleCount*wave.channels*sizeof(short)); // NOTE: Returns the number of samples to process (be careful! we ask for number of shorts!) - int numSamplesOgg = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, (short *)wave.data, wave.sampleCount*wave.channels); - TRACELOGD("[%s] Samples obtained: %i", fileName, numSamplesOgg); - + stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, (short *)wave.data, wave.sampleCount*wave.channels); TRACELOG(LOG_INFO, "[%s] OGG file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo"); stb_vorbis_close(oggFile); @@ -2115,29 +2107,6 @@ bool IsFileExtension(const char *fileName, const char *ext) return result; } - -// Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) -void TRACELOG(int msgType, const char *text, ...) -{ - va_list args; - va_start(args, text); - - switch (msgType) - { - case LOG_INFO: fprintf(stdout, "INFO: "); break; - case LOG_ERROR: fprintf(stdout, "ERROR: "); break; - case LOG_WARNING: fprintf(stdout, "WARNING: "); break; - case LOG_DEBUG: fprintf(stdout, "DEBUG: "); break; - default: break; - } - - vfprintf(stdout, text, args); - fprintf(stdout, "\n"); - - va_end(args); - - if (msgType == LOG_ERROR) exit(1); -} #endif #undef AudioBuffer From c5d5d19443575cc5b5961f25f3fa00d20dca627f Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 20:23:55 +0100 Subject: [PATCH 13/37] Remove trail spaces --- src/models.c | 2 +- src/text.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models.c b/src/models.c index 6d95441fe..935b97799 100644 --- a/src/models.c +++ b/src/models.c @@ -3455,7 +3455,7 @@ static Model LoadGLTF(const char *fileName) { /*********************************************************************************** - Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend) + Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend) Features: - Supports .gltf and .glb files diff --git a/src/text.c b/src/text.c index 08326cde0..fccb0198f 100644 --- a/src/text.c +++ b/src/text.c @@ -1446,7 +1446,7 @@ char *TextToUtf8(int *codepoints, int length) // Resize memory to text length + string NULL terminator void *ptr = RL_REALLOC(text, size + 1); - + if (ptr != NULL) text = (char *)ptr; return text; From 10464493391f1b4c7714caf0eb45cc76f0053c1e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 20:29:33 +0100 Subject: [PATCH 14/37] ADDED: LoadFileData(), SaveFileData() --- src/raylib.h | 2 ++ src/utils.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/raylib.h b/src/raylib.h index fa76b4e17..e6ba45250 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -949,6 +949,8 @@ RLAPI void TakeScreenshot(const char *fileName); // Takes a scr RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included) // Files management functions +RLAPI unsigned char *LoadFileData(const char *fileName, int *bytesRead); // Load file data as byte array (read) +RLAPI void SaveFileData(const char *fileName, void *data, int bytesToWrite); // Save data to file from byte array (write) RLAPI bool FileExists(const char *fileName); // Check if file exists RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists diff --git a/src/utils.c b/src/utils.c index 8a957b459..5d8f92b46 100644 --- a/src/utils.c +++ b/src/utils.c @@ -64,7 +64,7 @@ static int logTypeExit = LOG_ERROR; // Log type that exits static TraceLogCallback logCallback = NULL; // Log callback function pointer #if defined(PLATFORM_ANDROID) -static AAssetManager *assetManager = NULL; // Android assets manager pointer +static AAssetManager *assetManager = NULL; // Android assets manager pointer #endif #if defined(PLATFORM_UWP) @@ -163,6 +163,54 @@ void TraceLog(int logType, const char *text, ...) #endif // SUPPORT_TRACELOG } +// Load data from file into a buffer +unsigned char *LoadFileData(const char *fileName, int *bytesRead) +{ + unsigned char *data = NULL; + *bytesRead = 0; + + FILE *file = fopen(fileName, "rb"); + + if (file != NULL) + { + fseek(file, 0, SEEK_END); + int size = ftell(file); + fseek(file, 0, SEEK_SET); + + if (size > 0) + { + data = (unsigned char *)RL_MALLOC(sizeof(unsigned char)*size); + int count = fread(data, sizeof(unsigned char), size, file); + *bytesRead = count; + + if (count != size) TRACELOG(LOG_WARNING, "[%s] File partially read", fileName); + } + else TRACELOG(LOG_WARNING, "[%s] File could not be read", fileName); + + fclose(file); + } + else TRACELOG(LOG_WARNING, "[%s] File could not be opened", fileName); + + return data; +} + +// Save data to file from buffer +void SaveFileData(const char *fileName, void *data, int bytesToWrite) +{ + FILE *file = fopen(fileName, "wb"); + + if (file != NULL) + { + int count = fwrite(data, sizeof(unsigned char), bytesToWrite, file); + + if (count == 0) TRACELOG(LOG_WARNING, "[%s] File could not be written", fileName); + else if (count != bytesToWrite) TRACELOG(LOG_WARNING, "[%s] File partially written", fileName); + + fclose(file); + } + else TRACELOG(LOG_WARNING, "[%s] File could not be opened", fileName); +} + #if defined(PLATFORM_ANDROID) // Initialize asset manager from android app void InitAssetManager(AAssetManager *manager) From fa4e0c1a2645826dde90792e4081cbcbf6784968 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 20:47:08 +0100 Subject: [PATCH 15/37] Reviewed example --- examples/others/rlgl_standalone.c | 18 ++++++++++-------- src/rlgl.h | 1 - 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/examples/others/rlgl_standalone.c b/examples/others/rlgl_standalone.c index 506ddfdba..25490525f 100644 --- a/examples/others/rlgl_standalone.c +++ b/examples/others/rlgl_standalone.c @@ -54,6 +54,8 @@ #include // Windows/Context and inputs management +#inclde // Requried for: printf() + #define RED (Color){ 230, 41, 55, 255 } // Red #define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo) #define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray @@ -61,8 +63,8 @@ //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static void ErrorCallback(int error, const char* description); -static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +static void ErrorCallback(int error, const char *description); +static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // Drawing functions (uses rlgl functionality) static void DrawGrid(int slices, float spacing); @@ -86,10 +88,10 @@ int main(void) if (!glfwInit()) { - TraceLog(LOG_WARNING, "GLFW3: Can not initialize GLFW"); + printf("GLFW3: Can not initialize GLFW\n"); return 1; } - else TraceLog(LOG_INFO, "GLFW3: GLFW initialized successfully"); + else printf("GLFW3: GLFW initialized successfully\n"); glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_DEPTH_BITS, 16); @@ -105,7 +107,7 @@ int main(void) glfwTerminate(); return 2; } - else TraceLog(LOG_INFO, "GLFW3: Window created successfully"); + else printf("GLFW3: Window created successfully\n"); glfwSetWindowPos(window, 200, 200); @@ -215,13 +217,13 @@ int main(void) //---------------------------------------------------------------------------------- // GLFW3: Error callback -static void ErrorCallback(int error, const char* description) +static void ErrorCallback(int error, const char *description) { - TraceLog(LOG_ERROR, description); + fprintf(stderr, description); } // GLFW3: Keyboard callback -static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) +static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) { if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { diff --git a/src/rlgl.h b/src/rlgl.h index f6895f82a..ce6fdaf56 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -588,7 +588,6 @@ RLAPI void ToggleVrMode(void); // Enable/Disable VR exp RLAPI void BeginVrDrawing(void); // Begin VR simulator stereo rendering RLAPI void EndVrDrawing(void); // End VR simulator stereo rendering -RLAPI void TRACELOG(int msgType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data size in bytes (image or texture) #endif From 7912fac815c7bbebf55e1dea8c2484ef2f9b9db2 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 23:19:29 +0100 Subject: [PATCH 16/37] Correct typo --- examples/others/rlgl_standalone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/others/rlgl_standalone.c b/examples/others/rlgl_standalone.c index 25490525f..8f2e2b467 100644 --- a/examples/others/rlgl_standalone.c +++ b/examples/others/rlgl_standalone.c @@ -54,7 +54,7 @@ #include // Windows/Context and inputs management -#inclde // Requried for: printf() +#include // Required for: printf() #define RED (Color){ 230, 41, 55, 255 } // Red #define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo) From fadd74358b006de84c94315fdbaf8d7d16af0096 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 23:38:12 +0100 Subject: [PATCH 17/37] Security check --- src/rlgl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rlgl.h b/src/rlgl.h index ce6fdaf56..03aaf625c 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3004,7 +3004,7 @@ char *LoadText(const char *fileName) { text = (char *)RL_MALLOC(sizeof(char)*(size + 1)); int count = fread(text, sizeof(char), size, textFile); - text[count] = '\0'; + if (size == count) text[count] = '\0'; } fclose(textFile); From e5b5aea998229afb50b08f340700dc9a5eb4e7be Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 23:40:53 +0100 Subject: [PATCH 18/37] WARNING: RENAMED: Storage functions Renamed functions for consistency: - StorageLoadValue() > LoadStorageValue() - StorageSaveValue() > SaveStorageValue() --- src/core.c | 6 +++--- src/raylib.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/core.c b/src/core.c index 559565dd3..dcb266677 100644 --- a/src/core.c +++ b/src/core.c @@ -152,7 +152,7 @@ #endif #include // Required for: srand(), rand(), atexit() -#include // Required for: FILE, fopen(), fseek(), fread(), fwrite(), fclose() [Used in StorageSaveValue()/StorageLoadValue()] +#include // Required for: FILE, fopen(), fseek(), fread(), fwrite(), fclose() [Used in SaveStorageValue()/LoadStorageValue()] #include // Required for: strrchr(), strcmp(), strlen() #include // Required for: time() [Used in InitTimer()] #include // Required for: tan() [Used in BeginMode3D()] @@ -2179,7 +2179,7 @@ unsigned char *DecompressData(unsigned char *compData, int compDataLength, int * // Save integer value to storage file (to defined position) // NOTE: Storage positions is directly related to file memory layout (4 bytes each integer) -void StorageSaveValue(int position, int value) +void SaveStorageValue(int position, int value) { FILE *storageFile = NULL; @@ -2219,7 +2219,7 @@ void StorageSaveValue(int position, int value) // Load integer value from storage file (from defined position) // NOTE: If requested position could not be found, value 0 is returned -int StorageLoadValue(int position) +int LoadStorageValue(int position) { int value = 0; diff --git a/src/raylib.h b/src/raylib.h index e6ba45250..23ad8767e 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -972,8 +972,8 @@ RLAPI unsigned char *CompressData(unsigned char *data, int dataLength, int *comp RLAPI unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *dataLength); // Decompress data (DEFLATE algorythm) // Persistent storage management -RLAPI void StorageSaveValue(int position, int value); // Save integer value to storage file (to defined position) -RLAPI int StorageLoadValue(int position); // Load integer value from storage file (from defined position) +RLAPI void SaveStorageValue(int position, int value); // Save integer value to storage file (to defined position) +RLAPI int LoadStorageValue(int position); // Load integer value from storage file (from defined position) RLAPI void OpenURL(const char *url); // Open URL with default system browser (if available) From 5aed36e76db18d9b017c2c6c55c7170d5b2e5bfb Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 23:42:06 +0100 Subject: [PATCH 19/37] Tweaks on fullsccreen detection... --- src/core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core.c b/src/core.c index dcb266677..fa5b748f1 100644 --- a/src/core.c +++ b/src/core.c @@ -498,7 +498,7 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #endif #if defined(PLATFORM_WEB) -static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *e, void *userData); +static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData); static EM_BOOL EmscriptenKeyboardCallback(int eventType, const EmscriptenKeyboardEvent *keyEvent, void *userData); static EM_BOOL EmscriptenMouseCallback(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData); static EM_BOOL EmscriptenTouchCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData); @@ -703,6 +703,7 @@ void InitWindow(int width, int height, const char *title) #endif #if defined(PLATFORM_WEB) + // Detect fullscreen change events emscripten_set_fullscreenchange_callback("#canvas", NULL, 1, EmscriptenFullscreenChangeCallback); // Support keyboard events @@ -976,7 +977,7 @@ void SetWindowSize(int width, int height) #endif #if defined(PLATFORM_WEB) emscripten_set_canvas_size(width, height); // DEPRECATED! - + // TODO: Below functions should be used to replace previous one but // they do not seem to work properly //emscripten_set_canvas_element_size("canvas", width, height); @@ -1633,7 +1634,7 @@ int GetFPS(void) static float history[FPS_CAPTURE_FRAMES_COUNT] = { 0 }; static float average = 0, last = 0; float fpsFrame = GetFrameTime(); - + if (fpsFrame == 0) return 0; if ((GetTime() - last) > FPS_STEP) @@ -1644,7 +1645,7 @@ int GetFPS(void) history[index] = fpsFrame/FPS_CAPTURE_FRAMES_COUNT; average += history[index]; } - + return (int)roundf(1.0f/average); } @@ -4424,7 +4425,6 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event) #endif #if defined(PLATFORM_WEB) - // Register fullscreen change events static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const EmscriptenFullscreenChangeEvent *event, void *userData) { @@ -4437,10 +4437,12 @@ static EM_BOOL EmscriptenFullscreenChangeCallback(int eventType, const Emscripte if (event->isFullscreen) { + CORE.Window.fullscreen = true; TRACELOG(LOG_INFO, "Canvas scaled to fullscreen. ElementSize: (%ix%i), ScreenSize(%ix%i)", event->elementWidth, event->elementHeight, event->screenWidth, event->screenHeight); } else { + CORE.Window.fullscreen = false; TRACELOG(LOG_INFO, "Canvas scaled to windowed. ElementSize: (%ix%i), ScreenSize(%ix%i)", event->elementWidth, event->elementHeight, event->screenWidth, event->screenHeight); } From 229494766068e9bfb518e596e18d6f8413df3ff5 Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 26 Feb 2020 23:42:41 +0100 Subject: [PATCH 20/37] Update core_storage_values.c --- examples/core/core_storage_values.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/core/core_storage_values.c b/examples/core/core_storage_values.c index fbbbc5284..df757a4fd 100644 --- a/examples/core/core_storage_values.c +++ b/examples/core/core_storage_values.c @@ -43,14 +43,14 @@ int main(void) if (IsKeyPressed(KEY_ENTER)) { - StorageSaveValue(STORAGE_SCORE, score); - StorageSaveValue(STORAGE_HISCORE, hiscore); + SaveStorageValue(STORAGE_SCORE, score); + SaveStorageValue(STORAGE_HISCORE, hiscore); } else if (IsKeyPressed(KEY_SPACE)) { // NOTE: If requested position could not be found, value 0 is returned - score = StorageLoadValue(STORAGE_SCORE); - hiscore = StorageLoadValue(STORAGE_HISCORE); + score = LoadStorageValue(STORAGE_SCORE); + hiscore = LoadStorageValue(STORAGE_HISCORE); } framesCounter++; From 23bde477e56714c4d10e017abad00401207c1a12 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:18:15 +0100 Subject: [PATCH 21/37] REDESIGN: LoadStorageValue()/SaveStorageValue() Using new file I/O ABI --- examples/core/core_storage_values.c | 13 ++-- src/config.h | 2 + src/core.c | 96 ++++++++++++++++------------- src/utils.c | 7 ++- 4 files changed, 68 insertions(+), 50 deletions(-) diff --git a/examples/core/core_storage_values.c b/examples/core/core_storage_values.c index df757a4fd..02e4c2625 100644 --- a/examples/core/core_storage_values.c +++ b/examples/core/core_storage_values.c @@ -12,7 +12,10 @@ #include "raylib.h" // NOTE: Storage positions must start with 0, directly related to file memory layout -typedef enum { STORAGE_SCORE = 0, STORAGE_HISCORE } StorageData; +typedef enum { + STORAGE_POSITION_SCORE = 0, + STORAGE_POSITION_HISCORE = 1 +} StorageData; int main(void) { @@ -43,14 +46,14 @@ int main(void) if (IsKeyPressed(KEY_ENTER)) { - SaveStorageValue(STORAGE_SCORE, score); - SaveStorageValue(STORAGE_HISCORE, hiscore); + SaveStorageValue(STORAGE_POSITION_SCORE, score); + SaveStorageValue(STORAGE_POSITION_HISCORE, hiscore); } else if (IsKeyPressed(KEY_SPACE)) { // NOTE: If requested position could not be found, value 0 is returned - score = LoadStorageValue(STORAGE_SCORE); - hiscore = LoadStorageValue(STORAGE_HISCORE); + score = LoadStorageValue(STORAGE_POSITION_SCORE); + hiscore = LoadStorageValue(STORAGE_POSITION_HISCORE); } framesCounter++; diff --git a/src/config.h b/src/config.h index 91e0decf6..9367faa70 100644 --- a/src/config.h +++ b/src/config.h @@ -60,6 +60,8 @@ //#define SUPPORT_HIGH_DPI 1 // Support CompressData() and DecompressData() functions #define SUPPORT_COMPRESSION_API 1 +#define SUPPORT_DATA_STORAGE 1 +// Support saving binary data automatically to a generated storage.data file. This file is managed internally. //------------------------------------------------------------------------------------ // Module: rlgl - Configuration Flags diff --git a/src/core.c b/src/core.c index fa5b748f1..2f130555f 100644 --- a/src/core.c +++ b/src/core.c @@ -82,6 +82,9 @@ * provided by stb_image and stb_image_write libraries, so, those libraries must be enabled on textures module * for linkage * +* #define SUPPORT_DATA_STORAGE +* Support saving binary data automatically to a generated storage.data file. This file is managed internally. +* * DEPENDENCIES: * rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX. FreeBSD, OpenBSD, NetBSD, DragonFly) * raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion) @@ -152,7 +155,6 @@ #endif #include // Required for: srand(), rand(), atexit() -#include // Required for: FILE, fopen(), fseek(), fread(), fwrite(), fclose() [Used in SaveStorageValue()/LoadStorageValue()] #include // Required for: strrchr(), strcmp(), strlen() #include // Required for: time() [Used in InitTimer()] #include // Required for: tan() [Used in BeginMode3D()] @@ -283,12 +285,14 @@ #endif #define MAX_GAMEPADS 4 // Max number of gamepads supported -#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad) #define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad) +#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad) #define MAX_CHARS_QUEUE 16 // Max number of characters in the input queue -#define STORAGE_FILENAME "storage.data" +#if defined(SUPPORT_DATA_STORAGE) + #define STORAGE_DATA_FILE "storage.data" +#endif //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -2182,40 +2186,50 @@ unsigned char *DecompressData(unsigned char *compData, int compDataLength, int * // NOTE: Storage positions is directly related to file memory layout (4 bytes each integer) void SaveStorageValue(int position, int value) { - FILE *storageFile = NULL; - +#if defined(SUPPORT_DATA_STORAGE) char path[512] = { 0 }; #if defined(PLATFORM_ANDROID) strcpy(path, CORE.Android.internalDataPath); strcat(path, "/"); - strcat(path, STORAGE_FILENAME); + strcat(path, STORAGE_DATA_FILE); #else - strcpy(path, STORAGE_FILENAME); + strcpy(path, STORAGE_DATA_FILE); #endif - // Try open existing file to append data - storageFile = fopen(path, "rb+"); - - // If file doesn't exist, create a new storage data file - if (!storageFile) storageFile = fopen(path, "wb"); - - if (!storageFile) TRACELOG(LOG_WARNING, "Storage data file could not be created"); - else + int dataSize = 0; + unsigned char *fileData = LoadFileData(path, &dataSize); + + if (fileData != NULL) { - // Get file size - fseek(storageFile, 0, SEEK_END); - int fileSize = ftell(storageFile); // Size in bytes - fseek(storageFile, 0, SEEK_SET); - - if (fileSize < (position*sizeof(int))) TRACELOG(LOG_WARNING, "Storage position could not be found"); + if (dataSize <= (position*sizeof(int))) + { + // Increase data size up to position and store value + dataSize = (position + 1)*sizeof(int); + fileData = (unsigned char *)RL_REALLOC(fileData, dataSize); + int *dataPtr = (int *)fileData; + dataPtr[position] = value; + } else { - fseek(storageFile, (position*sizeof(int)), SEEK_SET); - fwrite(&value, 1, sizeof(int), storageFile); + // Replace value on selected position + int *dataPtr = (int *)fileData; + dataPtr[position] = value; } - - fclose(storageFile); + + SaveFileData(path, fileData, dataSize); + RL_FREE(fileData); } + else + { + dataSize = (position + 1)*sizeof(int); + fileData = (unsigned char *)RL_MALLOC(dataSize); + int *dataPtr = (int *)fileData; + dataPtr[position] = value; + + SaveFileData(path, fileData, dataSize); + RL_FREE(fileData); + } +#endif } // Load integer value from storage file (from defined position) @@ -2223,37 +2237,31 @@ void SaveStorageValue(int position, int value) int LoadStorageValue(int position) { int value = 0; - +#if defined(SUPPORT_DATA_STORAGE) char path[512] = { 0 }; #if defined(PLATFORM_ANDROID) strcpy(path, CORE.Android.internalDataPath); strcat(path, "/"); - strcat(path, STORAGE_FILENAME); + strcat(path, STORAGE_DATA_FILE); #else - strcpy(path, STORAGE_FILENAME); + strcpy(path, STORAGE_DATA_FILE); #endif - // Try open existing file to append data - FILE *storageFile = fopen(path, "rb"); - - if (!storageFile) TRACELOG(LOG_WARNING, "Storage data file could not be found"); - else + int dataSize = 0; + unsigned char *fileData = LoadFileData(path, &dataSize); + + if (fileData != NULL) { - // Get file size - fseek(storageFile, 0, SEEK_END); - int fileSize = ftell(storageFile); // Size in bytes - fseek(storageFile, 0, SEEK_SET); // Reset file pointer - - if (fileSize < (position*4)) TRACELOG(LOG_WARNING, "Storage position could not be found"); + if (dataSize < (position*4)) TRACELOG(LOG_WARNING, "Storage position could not be found"); else { - fseek(storageFile, (position*4), SEEK_SET); - fread(&value, 4, 1, storageFile); // Read 1 element of 4 bytes size + int *dataPtr = (int *)fileData; + value = dataPtr[position]; } - - fclose(storageFile); + + RL_FREE(fileData); } - +#endif return value; } diff --git a/src/utils.c b/src/utils.c index 5d8f92b46..302bc6913 100644 --- a/src/utils.c +++ b/src/utils.c @@ -173,6 +173,8 @@ unsigned char *LoadFileData(const char *fileName, int *bytesRead) if (file != NULL) { + // WARNING: On binary streams SEEK_END could not be found, + // using fseek() and ftell() could not work in some (rare) cases fseek(file, 0, SEEK_END); int size = ftell(file); fseek(file, 0, SEEK_SET); @@ -180,10 +182,13 @@ unsigned char *LoadFileData(const char *fileName, int *bytesRead) if (size > 0) { data = (unsigned char *)RL_MALLOC(sizeof(unsigned char)*size); + + // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] int count = fread(data, sizeof(unsigned char), size, file); *bytesRead = count; - if (count != size) TRACELOG(LOG_WARNING, "[%s] File partially read", fileName); + if (count != size) TRACELOG(LOG_WARNING, "[%s] File partially loaded", fileName); + else TRACELOG(LOG_INFO, "[%s] File loaded successfully", fileName); } else TRACELOG(LOG_WARNING, "[%s] File could not be read", fileName); From 89ecad1e29c24129ea7de9715afce738a94f9480 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:18:55 +0100 Subject: [PATCH 22/37] Review macros --- src/raylib.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/raylib.h b/src/raylib.h index 23ad8767e..ed8a3acef 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -104,13 +104,13 @@ #define RL_MALLOC(sz) malloc(sz) #endif #ifndef RL_CALLOC - #define RL_CALLOC(n,sz) calloc(n,sz) + #define RL_CALLOC(ptr,sz) calloc(ptr,sz) #endif #ifndef RL_REALLOC - #define RL_REALLOC(n,sz) realloc(n,sz) + #define RL_REALLOC(ptr,sz) realloc(ptr,sz) #endif #ifndef RL_FREE - #define RL_FREE(p) free(p) + #define RL_FREE(ptr) free(ptr) #endif // NOTE: MSC C++ compiler does not support compound literals (C99 feature) From 245ba2a152c078e1154fb74b2ba224029f2c0a93 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:19:13 +0100 Subject: [PATCH 23/37] LoadText(): Added comment --- src/rlgl.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/rlgl.h b/src/rlgl.h index 03aaf625c..1b4ef00cf 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -2996,6 +2996,9 @@ char *LoadText(const char *fileName) if (textFile != NULL) { + // WARNING: When reading a file as 'text' file, + // text mode causes carriage return-linefeed translation... + // ...but using fseek() should return correct byte-offset fseek(textFile, 0, SEEK_END); int size = ftell(textFile); fseek(textFile, 0, SEEK_SET); From b029fb6d319eaceab334312f56be0bf4f8e8535e Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:19:58 +0100 Subject: [PATCH 24/37] REDESIGNED: LoadFontEx() Using new file I/O ABI --- src/text.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/text.c b/src/text.c index fccb0198f..f890442ec 100644 --- a/src/text.c +++ b/src/text.c @@ -333,11 +333,11 @@ Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCou { Font font = { 0 }; +#if defined(SUPPORT_FILEFORMAT_TTF) font.baseSize = fontSize; font.charsCount = (charsCount > 0)? charsCount : 95; font.chars = LoadFontData(fileName, font.baseSize, fontChars, font.charsCount, FONT_DEFAULT); -#if defined(SUPPORT_FILEFORMAT_TTF) if (font.chars != NULL) { Image atlas = GenImageFontAtlas(font.chars, &font.recs, font.charsCount, font.baseSize, 2, 0); @@ -354,7 +354,6 @@ Font LoadFontEx(const char *fileName, int fontSize, int *fontChars, int charsCou } else font = GetFontDefault(); #else - UnloadFont(font); font = GetFontDefault(); #endif @@ -498,24 +497,16 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c #if defined(SUPPORT_FILEFORMAT_TTF) // Load font data (including pixel data) from TTF file - // NOTE: Loaded information should be enough to generate font image atlas, - // using any packaging method - FILE *fontFile = fopen(fileName, "rb"); // Load font file - - if (fontFile != NULL) + // NOTE: Loaded information should be enough to generate + // font image atlas, using any packaging method + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); + + if (fileData != NULL) { - fseek(fontFile, 0, SEEK_END); - long size = ftell(fontFile); // Get file size - fseek(fontFile, 0, SEEK_SET); // Reset file pointer - - unsigned char *fontBuffer = (unsigned char *)RL_MALLOC(size); - - fread(fontBuffer, size, 1, fontFile); - fclose(fontFile); - // Init font for data reading stbtt_fontinfo fontInfo; - if (!stbtt_InitFont(&fontInfo, fontBuffer, 0)) TRACELOG(LOG_WARNING, "Failed to init font!"); + if (!stbtt_InitFont(&fontInfo, fileData, 0)) TRACELOG(LOG_WARNING, "Failed to init font!"); // Calculate font scale factor float scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize); @@ -595,12 +586,9 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c */ } - RL_FREE(fontBuffer); + RL_FREE(fileData); if (genFontChars) RL_FREE(fontChars); } - else TRACELOG(LOG_WARNING, "[%s] TTF file could not be opened", fileName); -#else - TRACELOG(LOG_WARNING, "[%s] TTF support is disabled", fileName); #endif return chars; From 5100cb3e7fc736454ed9079f0e4086e1f9c5e6e3 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:21:21 +0100 Subject: [PATCH 25/37] REDESIGNED: LoadImageRaw(), LoadAnimatedGIF() Using new file I/O ABI --- src/textures.c | 72 +++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 50 deletions(-) diff --git a/src/textures.c b/src/textures.c index ade4acfa2..12f72ddfb 100644 --- a/src/textures.c +++ b/src/textures.c @@ -345,41 +345,25 @@ Image LoadImagePro(void *data, int width, int height, int format) Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize) { Image image = { 0 }; - - FILE *rawFile = fopen(fileName, "rb"); - - if (rawFile == NULL) + + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); + + if (fileData != NULL) { - TRACELOG(LOG_WARNING, "[%s] RAW image file could not be opened", fileName); - } - else - { - if (headerSize > 0) fseek(rawFile, headerSize, SEEK_SET); - + unsigned char *dataPtr = fileData; unsigned int size = GetPixelDataSize(width, height, format); + + if (headerSize > 0) dataPtr += headerSize; image.data = RL_MALLOC(size); // Allocate required memory in bytes + memcpy(image.data, dataPtr, size); // Copy required data to image + image.width = width; + image.height = height; + image.mipmaps = 1; + image.format = format; - // NOTE: fread() returns num read elements instead of bytes, - // to get bytes we need to read (1 byte size, elements) instead of (x byte size, 1 element) - int bytes = fread(image.data, 1, size, rawFile); - - // Check if data has been read successfully - if (bytes < size) - { - TRACELOG(LOG_WARNING, "[%s] RAW image data can not be read, wrong requested format or size", fileName); - - RL_FREE(image.data); - } - else - { - image.width = width; - image.height = height; - image.mipmaps = 1; - image.format = format; - } - - fclose(rawFile); + RL_FREE(fileData); } return image; @@ -2982,31 +2966,19 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle destR static Image LoadAnimatedGIF(const char *fileName, int *frames, int **delays) { Image image = { 0 }; - - FILE *gifFile = fopen(fileName, "rb"); - - if (gifFile == NULL) + + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); + + if (fileData != NULL) { - TRACELOG(LOG_WARNING, "[%s] Animated GIF file could not be opened", fileName); - } - else - { - fseek(gifFile, 0L, SEEK_END); - int size = ftell(gifFile); - fseek(gifFile, 0L, SEEK_SET); - - unsigned char *buffer = (unsigned char *)RL_CALLOC(size, sizeof(char)); - fread(buffer, sizeof(char), size, gifFile); - - fclose(gifFile); // Close file pointer - int comp = 0; - image.data = stbi_load_gif_from_memory(buffer, size, delays, &image.width, &image.height, frames, &comp, 4); + image.data = stbi_load_gif_from_memory(fileData, dataSize, delays, &image.width, &image.height, frames, &comp, 4); image.mipmaps = 1; image.format = UNCOMPRESSED_R8G8B8A8; - - free(buffer); + + RL_FREE(fileData); } return image; From 2a408d789c72f433ae5abdfde67dc8fa10232f11 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:21:51 +0100 Subject: [PATCH 26/37] REDESIGNED: LoadImage() -WIP- Using new file I/O ABI --- src/textures.c | 71 +++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/src/textures.c b/src/textures.c index 12f72ddfb..7099e78c2 100644 --- a/src/textures.c +++ b/src/textures.c @@ -195,6 +195,7 @@ Image LoadImage(const char *fileName) defined(SUPPORT_FILEFORMAT_TGA) || \ defined(SUPPORT_FILEFORMAT_GIF) || \ defined(SUPPORT_FILEFORMAT_PIC) || \ + defined(SUPPORT_FILEFORMAT_HDR) || \ defined(SUPPORT_FILEFORMAT_PSD) #define STBI_REQUIRED #endif @@ -225,53 +226,53 @@ Image LoadImage(const char *fileName) ) { #if defined(STBI_REQUIRED) - int imgWidth = 0; - int imgHeight = 0; - int imgBpp = 0; + // NOTE: Using stb_image to load images (Supports multiple image formats) - FILE *imFile = fopen(fileName, "rb"); - - if (imFile != NULL) + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); + + if (fileData != NULL) { - // NOTE: Using stb_image to load images (Supports multiple image formats) - image.data = stbi_load_from_file(imFile, &imgWidth, &imgHeight, &imgBpp, 0); + int comp = 0; + image.data = stbi_load_from_memory(fileData, dataSize, &image.width, &image.height, &comp, 0); - fclose(imFile); - - image.width = imgWidth; - image.height = imgHeight; image.mipmaps = 1; - - if (imgBpp == 1) image.format = UNCOMPRESSED_GRAYSCALE; - else if (imgBpp == 2) image.format = UNCOMPRESSED_GRAY_ALPHA; - else if (imgBpp == 3) image.format = UNCOMPRESSED_R8G8B8; - else if (imgBpp == 4) image.format = UNCOMPRESSED_R8G8B8A8; + + if (comp == 1) image.format = UNCOMPRESSED_GRAYSCALE; + else if (comp == 2) image.format = UNCOMPRESSED_GRAY_ALPHA; + else if (comp == 3) image.format = UNCOMPRESSED_R8G8B8; + else if (comp == 4) image.format = UNCOMPRESSED_R8G8B8A8; + + RL_FREE(fileData); } #endif } #if defined(SUPPORT_FILEFORMAT_HDR) else if (IsFileExtension(fileName, ".hdr")) { - int imgBpp = 0; - - FILE *imFile = fopen(fileName, "rb"); - - // Load 32 bit per channel floats data - //stbi_set_flip_vertically_on_load(true); - image.data = stbi_loadf_from_file(imFile, &image.width, &image.height, &imgBpp, 0); - - fclose(imFile); - - image.mipmaps = 1; - - if (imgBpp == 1) image.format = UNCOMPRESSED_R32; - else if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32; - else if (imgBpp == 4) image.format = UNCOMPRESSED_R32G32B32A32; - else +#if defined(STBI_REQUIRED) + int dataSize = 0; + unsigned char *fileData = LoadFileData(fileName, &dataSize); + + if (fileData != NULL) { - TRACELOG(LOG_WARNING, "[%s] Image fileformat not supported", fileName); - UnloadImage(image); + int comp = 0; + image.data = stbi_loadf_from_memory(fileData, dataSize, &image.width, &image.height, &comp, 0); + + image.mipmaps = 1; + + if (imgBpp == 1) image.format = UNCOMPRESSED_R32; + else if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32; + else if (imgBpp == 4) image.format = UNCOMPRESSED_R32G32B32A32; + else + { + TRACELOG(LOG_WARNING, "[%s] HDR Image fileformat not supported", fileName); + UnloadImage(image); + } + + RL_FREE(fileData); } +#endif } #endif #if defined(SUPPORT_FILEFORMAT_DDS) From 5ff07762351669e39e99a1751a97104a6db2c65f Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:33:09 +0100 Subject: [PATCH 27/37] Remove trail spaces and some tweaks --- examples/core/core_storage_values.c | 4 +- src/core.c | 88 ++++++++++++++--------------- src/raudio.c | 2 +- src/rlgl.h | 2 +- src/text.c | 4 +- src/textures.c | 24 ++++---- src/utils.c | 2 +- 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/examples/core/core_storage_values.c b/examples/core/core_storage_values.c index 02e4c2625..1592c0592 100644 --- a/examples/core/core_storage_values.c +++ b/examples/core/core_storage_values.c @@ -12,8 +12,8 @@ #include "raylib.h" // NOTE: Storage positions must start with 0, directly related to file memory layout -typedef enum { - STORAGE_POSITION_SCORE = 0, +typedef enum { + STORAGE_POSITION_SCORE = 0, STORAGE_POSITION_HISCORE = 1 } StorageData; diff --git a/src/core.c b/src/core.c index 2f130555f..b1eaf0f96 100644 --- a/src/core.c +++ b/src/core.c @@ -221,33 +221,33 @@ #include // Defines AWINDOW_FLAG_FULLSCREEN and others #include // Defines basic app state struct and manages activity - #include // Khronos EGL library - Native platform display device control functions - #include // Khronos OpenGL ES 2.0 library + #include // Khronos EGL library - Native platform display device control functions + #include // Khronos OpenGL ES 2.0 library #endif #if defined(PLATFORM_RPI) - #include // POSIX file control definitions - open(), creat(), fcntl() - #include // POSIX standard function definitions - read(), close(), STDIN_FILENO - #include // POSIX terminal control definitions - tcgetattr(), tcsetattr() - #include // POSIX threads management (inputs reading) - #include // POSIX directory browsing + #include // POSIX file control definitions - open(), creat(), fcntl() + #include // POSIX standard function definitions - read(), close(), STDIN_FILENO + #include // POSIX terminal control definitions - tcgetattr(), tcsetattr() + #include // POSIX threads management (inputs reading) + #include // POSIX directory browsing - #include // UNIX System call for device-specific input/output operations - ioctl() - #include // Linux: KDSKBMODE, K_MEDIUMRAM constants definition - #include // Linux: Keycodes constants definition (KEY_A, ...) - #include // Linux: Joystick support library + #include // UNIX System call for device-specific input/output operations - ioctl() + #include // Linux: KDSKBMODE, K_MEDIUMRAM constants definition + #include // Linux: Keycodes constants definition (KEY_A, ...) + #include // Linux: Joystick support library - #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions + #include "bcm_host.h" // Raspberry Pi VideoCore IV access functions - #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions - #include "EGL/eglext.h" // Khronos EGL library - Extensions - #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library + #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions + #include "EGL/eglext.h" // Khronos EGL library - Extensions + #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library #endif #if defined(PLATFORM_UWP) - #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions - #include "EGL/eglext.h" // Khronos EGL library - Extensions - #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library + #include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions + #include "EGL/eglext.h" // Khronos EGL library - Extensions + #include "GLES2/gl2.h" // Khronos OpenGL ES 2.0 library #endif #if defined(PLATFORM_WEB) @@ -299,22 +299,22 @@ //---------------------------------------------------------------------------------- #if defined(PLATFORM_RPI) typedef struct { - pthread_t threadId; // Event reading thread id - int fd; // File descriptor to the device it is assigned to - int eventNum; // Number of 'event' device - Rectangle absRange; // Range of values for absolute pointing devices (touchscreens) - int touchSlot; // Hold the touch slot number of the currently being sent multitouch block - bool isMouse; // True if device supports relative X Y movements - bool isTouch; // True if device supports absolute X Y movements and has BTN_TOUCH - bool isMultitouch; // True if device supports multiple absolute movevents and has BTN_TOUCH - bool isKeyboard; // True if device has letter keycodes - bool isGamepad; // True if device has gamepad buttons + pthread_t threadId; // Event reading thread id + int fd; // File descriptor to the device it is assigned to + int eventNum; // Number of 'event' device + Rectangle absRange; // Range of values for absolute pointing devices (touchscreens) + int touchSlot; // Hold the touch slot number of the currently being sent multitouch block + bool isMouse; // True if device supports relative X Y movements + bool isTouch; // True if device supports absolute X Y movements and has BTN_TOUCH + bool isMultitouch; // True if device supports multiple absolute movevents and has BTN_TOUCH + bool isKeyboard; // True if device has letter keycodes + bool isGamepad; // True if device has gamepad buttons } InputEventWorker; -typedef struct{ - int Contents[8]; - char Head; - char Tail; +typedef struct { + int contents[8]; // Key events FIFO contents (8 positions) + char head; // Key events FIFO head position + char tail; // Key events FIFO tail position } KeyEventFifo; #endif @@ -2198,7 +2198,7 @@ void SaveStorageValue(int position, int value) int dataSize = 0; unsigned char *fileData = LoadFileData(path, &dataSize); - + if (fileData != NULL) { if (dataSize <= (position*sizeof(int))) @@ -2215,7 +2215,7 @@ void SaveStorageValue(int position, int value) int *dataPtr = (int *)fileData; dataPtr[position] = value; } - + SaveFileData(path, fileData, dataSize); RL_FREE(fileData); } @@ -2225,7 +2225,7 @@ void SaveStorageValue(int position, int value) fileData = (unsigned char *)RL_MALLOC(dataSize); int *dataPtr = (int *)fileData; dataPtr[position] = value; - + SaveFileData(path, fileData, dataSize); RL_FREE(fileData); } @@ -2249,7 +2249,7 @@ int LoadStorageValue(int position) int dataSize = 0; unsigned char *fileData = LoadFileData(path, &dataSize); - + if (fileData != NULL) { if (dataSize < (position*4)) TRACELOG(LOG_WARNING, "Storage position could not be found"); @@ -2258,7 +2258,7 @@ int LoadStorageValue(int position) int *dataPtr = (int *)fileData; value = dataPtr[position]; } - + RL_FREE(fileData); } #endif @@ -3598,12 +3598,12 @@ static void PollInputEvents(void) for (int i = 0; i < 512; i++)CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; // Grab a keypress from the evdev fifo if avalable - if (CORE.Input.Keyboard.lastKeyPressed.Head != CORE.Input.Keyboard.lastKeyPressed.Tail) + if (CORE.Input.Keyboard.lastKeyPressed.head != CORE.Input.Keyboard.lastKeyPressed.tail) { - CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = CORE.Input.Keyboard.lastKeyPressed.Contents[CORE.Input.Keyboard.lastKeyPressed.Tail]; // Read the key from the buffer + CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.tail]; // Read the key from the buffer CORE.Input.Keyboard.keyPressedQueueCount++; - CORE.Input.Keyboard.lastKeyPressed.Tail = (CORE.Input.Keyboard.lastKeyPressed.Tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long) + CORE.Input.Keyboard.lastKeyPressed.tail = (CORE.Input.Keyboard.lastKeyPressed.tail + 1) & 0x07; // Increment the tail pointer forwards and binary wraparound after 7 (fifo is 8 elements long) } // Register previous mouse states @@ -4767,8 +4767,8 @@ static void InitEvdevInput(void) } // Reset keypress buffer - CORE.Input.Keyboard.lastKeyPressed.Head = 0; - CORE.Input.Keyboard.lastKeyPressed.Tail = 0; + CORE.Input.Keyboard.lastKeyPressed.head = 0; + CORE.Input.Keyboard.lastKeyPressed.tail = 0; // Reset keyboard key state for (int i = 0; i < 512; i++) CORE.Input.Keyboard.currentKeyState[i] = 0; @@ -5131,8 +5131,8 @@ static void *EventThread(void *arg) if (event.value > 0) { // Add the key int the fifo - CORE.Input.Keyboard.lastKeyPressed.Contents[CORE.Input.Keyboard.lastKeyPressed.Head] = keycode; // Put the data at the front of the fifo snake - CORE.Input.Keyboard.lastKeyPressed.Head = (CORE.Input.Keyboard.lastKeyPressed.Head + 1) & 0x07; // Increment the head pointer forwards and binary wraparound after 7 (fifo is 8 elements long) + CORE.Input.Keyboard.lastKeyPressed.contents[CORE.Input.Keyboard.lastKeyPressed.head] = keycode; // Put the data at the front of the fifo snake + CORE.Input.Keyboard.lastKeyPressed.head = (CORE.Input.Keyboard.lastKeyPressed.head + 1) & 0x07; // Increment the head pointer forwards and binary wraparound after 7 (fifo is 8 elements long) // TODO: This fifo is not fully threadsafe with multiple writers, so multiple keyboards hitting a key at the exact same time could miss a key (double write to head before it was incremented) } */ diff --git a/src/raudio.c b/src/raudio.c index 4e7118fdf..8a192c74f 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -165,7 +165,7 @@ typedef struct tagBITMAPINFOHEADER { #if defined(RAUDIO_STANDALONE) #include // Required for: strcmp() [Used in IsFileExtension()] - + #if !defined(TRACELOG) #define TRACELOG(level, ...) (void)0 #endif diff --git a/src/rlgl.h b/src/rlgl.h index 1b4ef00cf..b63ab61b8 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -2996,7 +2996,7 @@ char *LoadText(const char *fileName) if (textFile != NULL) { - // WARNING: When reading a file as 'text' file, + // WARNING: When reading a file as 'text' file, // text mode causes carriage return-linefeed translation... // ...but using fseek() should return correct byte-offset fseek(textFile, 0, SEEK_END); diff --git a/src/text.c b/src/text.c index f890442ec..c4ecd3deb 100644 --- a/src/text.c +++ b/src/text.c @@ -497,11 +497,11 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c #if defined(SUPPORT_FILEFORMAT_TTF) // Load font data (including pixel data) from TTF file - // NOTE: Loaded information should be enough to generate + // NOTE: Loaded information should be enough to generate // font image atlas, using any packaging method int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); - + if (fileData != NULL) { // Init font for data reading diff --git a/src/textures.c b/src/textures.c index 7099e78c2..aedfabc6b 100644 --- a/src/textures.c +++ b/src/textures.c @@ -230,19 +230,19 @@ Image LoadImage(const char *fileName) int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); - + if (fileData != NULL) { int comp = 0; image.data = stbi_load_from_memory(fileData, dataSize, &image.width, &image.height, &comp, 0); image.mipmaps = 1; - + if (comp == 1) image.format = UNCOMPRESSED_GRAYSCALE; else if (comp == 2) image.format = UNCOMPRESSED_GRAY_ALPHA; else if (comp == 3) image.format = UNCOMPRESSED_R8G8B8; else if (comp == 4) image.format = UNCOMPRESSED_R8G8B8A8; - + RL_FREE(fileData); } #endif @@ -253,14 +253,14 @@ Image LoadImage(const char *fileName) #if defined(STBI_REQUIRED) int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); - + if (fileData != NULL) { int comp = 0; image.data = stbi_loadf_from_memory(fileData, dataSize, &image.width, &image.height, &comp, 0); image.mipmaps = 1; - + if (imgBpp == 1) image.format = UNCOMPRESSED_R32; else if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32; else if (imgBpp == 4) image.format = UNCOMPRESSED_R32G32B32A32; @@ -269,7 +269,7 @@ Image LoadImage(const char *fileName) TRACELOG(LOG_WARNING, "[%s] HDR Image fileformat not supported", fileName); UnloadImage(image); } - + RL_FREE(fileData); } #endif @@ -346,15 +346,15 @@ Image LoadImagePro(void *data, int width, int height, int format) Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize) { Image image = { 0 }; - + int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); - + if (fileData != NULL) { unsigned char *dataPtr = fileData; unsigned int size = GetPixelDataSize(width, height, format); - + if (headerSize > 0) dataPtr += headerSize; image.data = RL_MALLOC(size); // Allocate required memory in bytes @@ -2967,10 +2967,10 @@ void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle destR static Image LoadAnimatedGIF(const char *fileName, int *frames, int **delays) { Image image = { 0 }; - + int dataSize = 0; unsigned char *fileData = LoadFileData(fileName, &dataSize); - + if (fileData != NULL) { int comp = 0; @@ -2978,7 +2978,7 @@ static Image LoadAnimatedGIF(const char *fileName, int *frames, int **delays) image.mipmaps = 1; image.format = UNCOMPRESSED_R8G8B8A8; - + RL_FREE(fileData); } diff --git a/src/utils.c b/src/utils.c index 302bc6913..9aaf548b4 100644 --- a/src/utils.c +++ b/src/utils.c @@ -182,7 +182,7 @@ unsigned char *LoadFileData(const char *fileName, int *bytesRead) if (size > 0) { data = (unsigned char *)RL_MALLOC(sizeof(unsigned char)*size); - + // NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements] int count = fread(data, sizeof(unsigned char), size, file); *bytesRead = count; From acfa967e891997e862d1c77dac21ae9a484017c5 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 13:56:27 +0100 Subject: [PATCH 28/37] Corrected issue with variable name --- src/textures.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/textures.c b/src/textures.c index aedfabc6b..fcd4d03cc 100644 --- a/src/textures.c +++ b/src/textures.c @@ -261,9 +261,9 @@ Image LoadImage(const char *fileName) image.mipmaps = 1; - if (imgBpp == 1) image.format = UNCOMPRESSED_R32; - else if (imgBpp == 3) image.format = UNCOMPRESSED_R32G32B32; - else if (imgBpp == 4) image.format = UNCOMPRESSED_R32G32B32A32; + if (comp == 1) image.format = UNCOMPRESSED_R32; + else if (comp == 3) image.format = UNCOMPRESSED_R32G32B32; + else if (comp == 4) image.format = UNCOMPRESSED_R32G32B32A32; else { TRACELOG(LOG_WARNING, "[%s] HDR Image fileformat not supported", fileName); From eb86d69a3866ea0d66d2ddc2a6f5624c208e9937 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 16:14:31 +0100 Subject: [PATCH 29/37] Review default config flags --- src/config.h | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/config.h b/src/config.h index 9367faa70..9b1b1ee2c 100644 --- a/src/config.h +++ b/src/config.h @@ -53,15 +53,15 @@ // Wait for events passively (sleeping while no events) instead of polling them actively every frame //#define SUPPORT_EVENTS_WAITING 1 // Allow automatic screen capture of current screen pressing F12, defined in KeyCallback() -#define SUPPORT_SCREEN_CAPTURE 1 +//#define SUPPORT_SCREEN_CAPTURE 1 // Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback() -#define SUPPORT_GIF_RECORDING 1 +//#define SUPPORT_GIF_RECORDING 1 // Allow scale all the drawn content to match the high-DPI equivalent size (only PLATFORM_DESKTOP) //#define SUPPORT_HIGH_DPI 1 // Support CompressData() and DecompressData() functions -#define SUPPORT_COMPRESSION_API 1 -#define SUPPORT_DATA_STORAGE 1 +#define SUPPORT_COMPRESSION_API 1 // Support saving binary data automatically to a generated storage.data file. This file is managed internally. +#define SUPPORT_DATA_STORAGE 1 //------------------------------------------------------------------------------------ // Module: rlgl - Configuration Flags @@ -87,14 +87,15 @@ //#define SUPPORT_FILEFORMAT_BMP 1 //#define SUPPORT_FILEFORMAT_TGA 1 //#define SUPPORT_FILEFORMAT_JPG 1 -#define SUPPORT_FILEFORMAT_GIF 1 +#define SUPPORT_FILEFORMAT_GIF 1 //#define SUPPORT_FILEFORMAT_PSD 1 -#define SUPPORT_FILEFORMAT_DDS 1 -#define SUPPORT_FILEFORMAT_HDR 1 +//#define SUPPORT_FILEFORMAT_DDS 1 +//#define SUPPORT_FILEFORMAT_HDR 1 //#define SUPPORT_FILEFORMAT_KTX 1 //#define SUPPORT_FILEFORMAT_ASTC 1 //#define SUPPORT_FILEFORMAT_PKM 1 //#define SUPPORT_FILEFORMAT_PVR 1 + // Support image export functionality (.png, .bmp, .tga, .jpg) #define SUPPORT_IMAGE_EXPORT 1 // Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop... @@ -119,7 +120,7 @@ // Selected desired model fileformats to be supported for loading #define SUPPORT_FILEFORMAT_OBJ 1 #define SUPPORT_FILEFORMAT_MTL 1 -#define SUPPORT_FILEFORMAT_IQM 1 +//#define SUPPORT_FILEFORMAT_IQM 1 #define SUPPORT_FILEFORMAT_GLTF 1 // Support procedural mesh generation functions, uses external par_shapes.h library // NOTE: Some generated meshes DO NOT include generated texture coordinates @@ -133,8 +134,8 @@ #define SUPPORT_FILEFORMAT_OGG 1 #define SUPPORT_FILEFORMAT_XM 1 #define SUPPORT_FILEFORMAT_MOD 1 -#define SUPPORT_FILEFORMAT_FLAC 1 -#define SUPPORT_FILEFORMAT_MP3 1 +//#define SUPPORT_FILEFORMAT_FLAC 1 +//#define SUPPORT_FILEFORMAT_MP3 1 //------------------------------------------------------------------------------------ // Module: utils - Configuration Flags From 1be68d8cfec2676dc7bcbb13c06c270f9a7597ab Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 16:14:50 +0100 Subject: [PATCH 30/37] Tweak on variable init --- src/text.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/text.c b/src/text.c index c4ecd3deb..58596f8fc 100644 --- a/src/text.c +++ b/src/text.c @@ -1644,7 +1644,6 @@ static Font LoadBMFont(const char *fileName) #define MAX_BUFFER_SIZE 256 Font font = { 0 }; - font.texture.id = 0; char buffer[MAX_BUFFER_SIZE] = { 0 }; char *searchPoint = NULL; From ac73e3b5e2d46805f32aa3cc57cd7fce2e2110dc Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 16:15:20 +0100 Subject: [PATCH 31/37] REDESIGN: ExportWave() Use new file I/O ABI --- src/raudio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/raudio.c b/src/raudio.c index 8a192c74f..c9b9b41c4 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -744,9 +744,7 @@ void ExportWave(Wave wave, const char *fileName) { // Export raw sample data (without header) // NOTE: It's up to the user to track wave parameters - FILE *rawFile = fopen(fileName, "wb"); - success = fwrite(wave.data, wave.sampleCount*wave.channels*wave.sampleSize/8, 1, rawFile); - fclose(rawFile); + SaveFileData(fileName, wave.data, wave.sampleCount*wave.channels*wave.sampleSize/8); } if (success) TRACELOG(LOG_INFO, "Wave exported successfully: %s", fileName); From b2098a2d60ea343a68bb8d3aa3537e06518aaaca Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 16:15:58 +0100 Subject: [PATCH 32/37] REDESIGN: ExportImage() Use new file I/O ABI --- src/textures.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/textures.c b/src/textures.c index fcd4d03cc..c50acf99a 100644 --- a/src/textures.c +++ b/src/textures.c @@ -829,9 +829,7 @@ void ExportImage(Image image, const char *fileName) { // Export raw pixel data (without header) // NOTE: It's up to the user to track image parameters - FILE *rawFile = fopen(fileName, "wb"); - success = fwrite(image.data, GetPixelDataSize(image.width, image.height, image.format), 1, rawFile); - fclose(rawFile); + SaveFileData(fileName, image.data, GetPixelDataSize(image.width, image.height, image.format)); } RL_FREE(imgData); @@ -3044,7 +3042,7 @@ static Image LoadDDS(const char *fileName) else { // Verify the type of file - char ddsHeaderId[4]; + char ddsHeaderId[4] = { 0 }; fread(ddsHeaderId, 4, 1, ddsFile); @@ -3054,7 +3052,7 @@ static Image LoadDDS(const char *fileName) } else { - DDSHeader ddsHeader; + DDSHeader ddsHeader = { 0 }; // Get the image header fread(&ddsHeader, sizeof(DDSHeader), 1, ddsFile); @@ -3223,7 +3221,7 @@ static Image LoadPKM(const char *fileName) } else { - PKMHeader pkmHeader; + PKMHeader pkmHeader = { 0 }; // Get the image header fread(&pkmHeader, sizeof(PKMHeader), 1, pkmFile); @@ -3316,7 +3314,7 @@ static Image LoadKTX(const char *fileName) } else { - KTXHeader ktxHeader; + KTXHeader ktxHeader = { 0 }; // Get the image header fread(&ktxHeader, sizeof(KTXHeader), 1, ktxFile); @@ -3397,7 +3395,7 @@ static int SaveKTX(Image image, const char *fileName) if (ktxFile == NULL) TRACELOG(LOG_WARNING, "[%s] KTX image file could not be created", fileName); else { - KTXHeader ktxHeader; + KTXHeader ktxHeader = { 0 }; // KTX identifier (v1.1) //unsigned char id[12] = { '«', 'K', 'T', 'X', ' ', '1', '1', '»', '\r', '\n', '\x1A', '\n' }; @@ -3533,7 +3531,7 @@ static Image LoadPVR(const char *fileName) // Load different PVR data formats if (pvrVersion == 0x50) { - PVRHeaderV3 pvrHeader; + PVRHeaderV3 pvrHeader = { 0 }; // Get PVR image header fread(&pvrHeader, sizeof(PVRHeaderV3), 1, pvrFile); @@ -3643,7 +3641,7 @@ static Image LoadASTC(const char *fileName) } else { - ASTCHeader astcHeader; + ASTCHeader astcHeader = { 0 }; // Get ASTC image header fread(&astcHeader, sizeof(ASTCHeader), 1, astcFile); From c8464bc731f57587a1c7e7cbad440bf89cc99621 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 16:22:34 +0100 Subject: [PATCH 33/37] Corrected return value --- src/textures.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textures.c b/src/textures.c index c50acf99a..95a6f1138 100644 --- a/src/textures.c +++ b/src/textures.c @@ -830,6 +830,7 @@ void ExportImage(Image image, const char *fileName) // Export raw pixel data (without header) // NOTE: It's up to the user to track image parameters SaveFileData(fileName, image.data, GetPixelDataSize(image.width, image.height, image.format)); + success = true; } RL_FREE(imgData); From 05992a6fce2f9233ab4dec842301290c328319a8 Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 27 Feb 2020 16:37:32 +0100 Subject: [PATCH 34/37] Tweaks --- src/raudio.c | 1 + src/raylib.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/raudio.c b/src/raudio.c index c9b9b41c4..8dd400156 100644 --- a/src/raudio.c +++ b/src/raudio.c @@ -745,6 +745,7 @@ void ExportWave(Wave wave, const char *fileName) // Export raw sample data (without header) // NOTE: It's up to the user to track wave parameters SaveFileData(fileName, wave.data, wave.sampleCount*wave.channels*wave.sampleSize/8); + success = true; } if (success) TRACELOG(LOG_INFO, "Wave exported successfully: %s", fileName); diff --git a/src/raylib.h b/src/raylib.h index ed8a3acef..48728fc17 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -104,7 +104,7 @@ #define RL_MALLOC(sz) malloc(sz) #endif #ifndef RL_CALLOC - #define RL_CALLOC(ptr,sz) calloc(ptr,sz) + #define RL_CALLOC(n,sz) calloc(n,sz) #endif #ifndef RL_REALLOC #define RL_REALLOC(ptr,sz) realloc(ptr,sz) From f2247c6f0a2c200937f40c09d829e48360d42df7 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 28 Feb 2020 00:32:46 +0100 Subject: [PATCH 35/37] REVIEWED: LoadText() --- src/rlgl.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/rlgl.h b/src/rlgl.h index b63ab61b8..0bbbf2fd1 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3007,7 +3007,14 @@ char *LoadText(const char *fileName) { text = (char *)RL_MALLOC(sizeof(char)*(size + 1)); int count = fread(text, sizeof(char), size, textFile); - if (size == count) text[count] = '\0'; + + // WARNING: \r\n is converted to \n on reading, so, + // read bytes count gets reduced by the number of lines + if (count < size) + { + text = RL_REALLOC(text, count + 1); + text[count] = '\0'; + } } fclose(textFile); From 572969d8b7889856bf59a470c5ffe56a2d14761f Mon Sep 17 00:00:00 2001 From: brankoku <48296877+brankoku@users.noreply.github.com> Date: Fri, 28 Feb 2020 02:23:05 -0500 Subject: [PATCH 36/37] `LoadText()` tweak (#1113) Guarantee string is zero-terminated --- src/rlgl.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/rlgl.h b/src/rlgl.h index 0bbbf2fd1..f2c796dee 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -3013,8 +3013,10 @@ char *LoadText(const char *fileName) if (count < size) { text = RL_REALLOC(text, count + 1); - text[count] = '\0'; } + + // zero-terminate the string + text[count] = '\0'; } fclose(textFile); From 1ee6290fcfebea2fa3a0a5a68c1c395974ebb436 Mon Sep 17 00:00:00 2001 From: Ray Date: Fri, 28 Feb 2020 12:54:39 +0100 Subject: [PATCH 37/37] Replaced fabs() by fabsf() when required --- src/models.c | 12 ++++++------ src/rlgl.h | 6 +++--- src/shapes.c | 11 +++++------ src/textures.c | 5 +++-- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/models.c b/src/models.c index 935b97799..60e9ca7ae 100644 --- a/src/models.c +++ b/src/models.c @@ -45,10 +45,10 @@ #include "utils.h" // Required for: fopen() Android mapping -#include // Required for: malloc(), free(), fabs() +#include // Required for: malloc(), free() #include // Required for: FILE, fopen(), fclose() #include // Required for: strncmp() [Used in LoadModelAnimations()], strlen() [Used in LoadTextureFromCgltfImage()] -#include // Required for: sinf(), cosf(), sqrtf() +#include // Required for: sinf(), cosf(), sqrtf(), fabsf() #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 @@ -2513,9 +2513,9 @@ void DrawBoundingBox(BoundingBox box, Color color) { Vector3 size; - size.x = (float)fabs(box.max.x - box.min.x); - size.y = (float)fabs(box.max.y - box.min.y); - size.z = (float)fabs(box.max.z - box.min.z); + size.x = fabsf(box.max.x - box.min.x); + size.y = fabsf(box.max.y - box.min.y); + size.z = fabsf(box.max.z - box.min.z); Vector3 center = { box.min.x + size.x/2.0f, box.min.y + size.y/2.0f, box.min.z + size.z/2.0f }; @@ -2761,7 +2761,7 @@ RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight) RayHitInfo result = { 0 }; - if (fabs(ray.direction.y) > EPSILON) + if (fabsf(ray.direction.y) > EPSILON) { float distance = (ray.position.y - groundHeight)/-ray.direction.y; diff --git a/src/rlgl.h b/src/rlgl.h index f2c796dee..536f8103e 100644 --- a/src/rlgl.h +++ b/src/rlgl.h @@ -612,10 +612,10 @@ RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data #endif #endif -#include // Required for: malloc(), free(), fabs() +#include // Required for: malloc(), free() #include // Required for: fopen(), fseek(), fread(), fclose() [LoadText] #include // Required for: strcmp(), strlen() [Used in rlglInit(), on extensions loading] -#include // Required for: atan2f() +#include // Required for: atan2f(), fabs() #if !defined(RLGL_STANDALONE) #include "raymath.h" // Required for: Vector3 and Matrix functions @@ -3662,7 +3662,7 @@ void SetVrConfiguration(VrDeviceInfo hmd, Shader distortion) // Compute distortion scale parameters // NOTE: To get lens max radius, lensShift must be normalized to [-1..1] - float lensRadius = (float)fabs(-1.0f - 4.0f*lensShift); + float lensRadius = fabsf(-1.0f - 4.0f*lensShift); float lensRadiusSq = lensRadius*lensRadius; float distortionScale = hmd.lensDistortionValues[0] + hmd.lensDistortionValues[1]*lensRadiusSq + diff --git a/src/shapes.c b/src/shapes.c index 4fb38867e..02c0eeb7e 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -42,8 +42,7 @@ #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -#include // Required for: fabs() -#include // Required for: sinf(), asinf(), cosf(), acosf(), sqrtf() +#include // Required for: sinf(), asinf(), cosf(), acosf(), sqrtf(), fabsf() //---------------------------------------------------------------------------------- // Defines and Macros @@ -1471,8 +1470,8 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec) int recCenterX = (int)(rec.x + rec.width/2.0f); int recCenterY = (int)(rec.y + rec.height/2.0f); - float dx = (float)fabs(center.x - recCenterX); - float dy = (float)fabs(center.y - recCenterY); + float dx = fabsf(center.x - (float)recCenterX); + float dy = fabsf(center.y - (float)recCenterY); if (dx > (rec.width/2.0f + radius)) { return false; } if (dy > (rec.height/2.0f + radius)) { return false; } @@ -1493,8 +1492,8 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2) if (CheckCollisionRecs(rec1, rec2)) { - float dxx = (float)fabs(rec1.x - rec2.x); - float dyy = (float)fabs(rec1.y - rec2.y); + float dxx = fabsf(rec1.x - rec2.x); + float dyy = fabsf(rec1.y - rec2.y); if (rec1.x <= rec2.x) { diff --git a/src/textures.c b/src/textures.c index 95a6f1138..98b060d7b 100644 --- a/src/textures.c +++ b/src/textures.c @@ -64,9 +64,10 @@ #include "config.h" // Defines module configuration flags #endif -#include // Required for: malloc(), free(), fabs() +#include // Required for: malloc(), free() #include // Required for: FILE, fopen(), fclose(), fread() #include // Required for: strlen() [Used in ImageTextEx()] +#include // Required for: fabsf() #include "utils.h" // Required for: fopen() Android mapping @@ -2688,7 +2689,7 @@ void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float sc // Draw a part of a texture (defined by a rectangle) void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint) { - Rectangle destRec = { position.x, position.y, (float)fabs(sourceRec.width), (float)fabs(sourceRec.height) }; + Rectangle destRec = { position.x, position.y, fabsf(sourceRec.width), fabsf(sourceRec.height) }; Vector2 origin = { 0.0f, 0.0f }; DrawTexturePro(texture, sourceRec, destRec, origin, 0.0f, tint);