Browse Source

Updated to latest raylib 7ef114d.

Brucey 5 years ago
parent
commit
8944073c62
57 changed files with 1966 additions and 1632 deletions
  1. 38 0
      examples/core/core_window_letterbox.bmx
  2. 5 0
      examples/textures/textures_image_drawing.bmx
  3. 12 1
      lib.mod/common.bmx
  4. 77 3
      lib.mod/lib.bmx
  5. 1 24
      lib.mod/raylib/.gitignore
  6. 10 1
      lib.mod/raylib/BINDINGS.md
  7. 28 7
      lib.mod/raylib/CHANGELOG
  8. 6 6
      lib.mod/raylib/CONTRIBUTING.md
  9. 89 60
      lib.mod/raylib/HISTORY.md
  10. 59 19
      lib.mod/raylib/README.md
  11. 4 3
      lib.mod/raylib/ROADMAP.md
  12. 1 1
      lib.mod/raylib/appveyor.yml
  13. 4 3
      lib.mod/raylib/examples/Makefile
  14. 10 9
      lib.mod/raylib/examples/Makefile.Android
  15. 5 4
      lib.mod/raylib/examples/core/core_basic_window.c
  16. 23 1
      lib.mod/raylib/examples/core/core_window_letterbox.c
  17. BIN
      lib.mod/raylib/examples/core/core_window_letterbox.png
  18. 0 1
      lib.mod/raylib/examples/models/models_animation.c
  19. 3 0
      lib.mod/raylib/examples/models/models_material_pbr.c
  20. 0 133
      lib.mod/raylib/examples/models/resources/shaders/glsl100/brdf.fs
  21. 0 25
      lib.mod/raylib/examples/models/resources/shaders/glsl100/brdf.vs
  22. 0 58
      lib.mod/raylib/examples/models/resources/shaders/glsl100/irradiance.fs
  23. 0 298
      lib.mod/raylib/examples/models/resources/shaders/glsl100/pbr.fs
  24. 0 49
      lib.mod/raylib/examples/models/resources/shaders/glsl100/pbr.vs
  25. 0 120
      lib.mod/raylib/examples/models/resources/shaders/glsl100/prefilter.fs
  26. BIN
      lib.mod/raylib/examples/shaders/resources/raysan.png
  27. 77 0
      lib.mod/raylib/examples/shaders/resources/shaders/glsl100/spotlight.fs
  28. 59 0
      lib.mod/raylib/examples/shaders/resources/shaders/glsl120/base_lighting.vs
  29. 92 0
      lib.mod/raylib/examples/shaders/resources/shaders/glsl120/fog.fs
  30. 65 0
      lib.mod/raylib/examples/shaders/resources/shaders/glsl330/spotlight.fs
  31. 3 7
      lib.mod/raylib/examples/shaders/shaders_raymarching.c
  32. 262 0
      lib.mod/raylib/examples/shaders/shaders_spotlight.c
  33. BIN
      lib.mod/raylib/examples/shaders/shaders_spotlight.png
  34. 5 0
      lib.mod/raylib/examples/textures/textures_image_drawing.c
  35. BIN
      lib.mod/raylib/examples/textures/textures_image_drawing.png
  36. 82 1
      lib.mod/raylib/projects/Notepad++/c_raylib.xml
  37. 11 8
      lib.mod/raylib/projects/scripts/build-windows.bat
  38. 7 2
      lib.mod/raylib/src/CMakeLists.txt
  39. 16 17
      lib.mod/raylib/src/Makefile
  40. 24 26
      lib.mod/raylib/src/camera.h
  41. 7 7
      lib.mod/raylib/src/config.h
  42. 149 194
      lib.mod/raylib/src/core.c
  43. 98 70
      lib.mod/raylib/src/models.c
  44. 100 73
      lib.mod/raylib/src/raudio.c
  45. 60 39
      lib.mod/raylib/src/raylib.h
  46. 1 1
      lib.mod/raylib/src/raylib.rc
  47. BIN
      lib.mod/raylib/src/raylib.rc.data
  48. 7 11
      lib.mod/raylib/src/raymath.h
  49. 99 95
      lib.mod/raylib/src/rlgl.h
  50. 5 5
      lib.mod/raylib/src/shell.html
  51. 84 82
      lib.mod/raylib/src/text.c
  52. 200 107
      lib.mod/raylib/src/textures.c
  53. 47 33
      lib.mod/raylib/src/utils.c
  54. 2 2
      lib.mod/raylib/src/utils.h
  55. 9 8
      lib.mod/raylib/templates/advance_game/Makefile.Android
  56. 10 9
      lib.mod/raylib/templates/simple_game/Makefile.Android
  57. 10 9
      lib.mod/raylib/templates/standard_game/Makefile.Android

+ 38 - 0
examples/core/core_window_letterbox.bmx

@@ -1,6 +1,10 @@
 SuperStrict
 
 Framework Ray.Lib
+Import Text.Format
+
+Local defFormatter:TFormatter = TFormatter.Create("Default Mouse: [%i , %i]")
+Local virFormatter:TFormatter = TFormatter.Create("Virtual Mouse: [%i , %i]")
 
 Const windowWidth:Int = 800
 Const windowHeight:Int = 450
@@ -40,6 +44,13 @@ While Not WindowShouldClose()    ' Detect window close button or ESC key
 	End If
 	'----------------------------------------------------------------------------------
 
+	' Update virtual mouse (clamped mouse value behind game screen)
+	Local mouse:RVector2 = GetMousePosition()
+	Local virtualMouse:RVector2
+	virtualMouse.x = (mouse.x - (GetScreenWidth() - (gameScreenWidth * scale)) * 0.5) / scale
+	virtualMouse.y = (mouse.y - (GetScreenHeight() - (gameScreenHeight * scale)) * 0.5) / scale
+	virtualMouse = ClampValue(virtualMouse, New RVector2(0, 0), New RVector2(gameScreenWidth, gameScreenHeight)) 
+	
 	' Draw
 	'----------------------------------------------------------------------------------
 	BeginDrawing()
@@ -56,6 +67,9 @@ While Not WindowShouldClose()    ' Detect window close button or ESC key
 
 			DrawText("If executed inside a window,~nyou can resize the window,~nand see the screen scaling!", 10, 25, 20, WHITE)
 
+			DrawText(defFormatter.Clear().Arg(Int(mouse.x)).Arg(Int(mouse.y)).Format(), 350, 25, 20, GREEN)
+			DrawText(virFormatter.Clear().Arg(Int(virtualMouse.x)).Arg(Int(virtualMouse.y)).Format(), 350, 55, 20, YELLOW)
+
 		EndTextureMode()
 
 		' Draw RenderTexture2D to window, properly scaled
@@ -74,3 +88,27 @@ UnloadRenderTexture(target)    ' Unload render texture
 
 CloseWindow()                  ' Close window and OpenGL context
 '--------------------------------------------------------------------------------------
+
+' Clamp Vector2 value with min and max and return a new vector2
+' NOTE: Required for virtual mouse, to clamp inside virtual game size
+Function ClampValue:RVector2(value:RVector2, minimum:RVector2, maximum:RVector2)
+	Local result:RVector2 = value
+
+	If result.x > maximum.x Then
+		result.x = maximum.x
+	End If
+	
+	If result.x < minimum.x Then
+		result.x = minimum.x
+	End If
+	
+	If result.y > maximum.y Then
+		result.y = maximum.y
+	End If
+	
+	If result.y < minimum.y Then
+		result.y = minimum.y
+	End If
+
+	Return result
+End Function

+ 5 - 0
examples/textures/textures_image_drawing.bmx

@@ -22,6 +22,11 @@ Local parrots:RImage = LoadImage("../../lib.mod/raylib/examples/textures/resourc
 ImageDraw(parrots, cat, New RRectangle(0, 0, cat.width, cat.height), New RRectangle(30, 40, cat.width*1.5, cat.height*1.5), WHITE)
 ImageCrop(parrots, New RRectangle(0, 50, parrots.width, parrots.height - 100)) ' Crop resulting image
 
+' Draw on the image with a few image draw methods
+ImageDrawPixel(parrots, 10, 10, RAYWHITE)
+ImageDrawCircle(parrots, 10, 10, 5, RAYWHITE)
+ImageDrawRectangle(parrots, 5, 20, 10, 10, RAYWHITE)
+
 UnloadImage(cat)       ' Unload image from RAM
 
 ' Load custom font for frawing on image

+ 12 - 1
lib.mod/common.bmx

@@ -45,6 +45,7 @@ Extern
 	Function bmx_raylib_IsWindowMinimized:Int()="IsWindowMinimized"
 	Function bmx_raylib_IsWindowResized:Int()="IsWindowResized"
 	Function bmx_raylib_IsWindowHidden:Int()="IsWindowHidden"
+	Function bmx_raylib_IsWindowFullscreen:Int()="IsWindowFullscreen"
 	Function bmx_raylib_ToggleFullscreen()="ToggleFullscreen"
 	Function bmx_raylib_UnhideWindow()="UnhideWindow"
 	Function bmx_raylib_HideWindow()="HideWindow"
@@ -338,7 +339,7 @@ Extern
 	Function bmx_raylib_ImageText:RImage(txt:Byte Ptr, FontSize:Int, color:RColor)="ImageText"
 	Function bmx_raylib_ImageTextEx:RImage(font:RFont, txt:Byte Ptr, FontSize:Float, spacing:Float, tint:RColor)="ImageTextEx"
 	Function bmx_raylib_ImageDraw(dst:RImage Var, src:RImage, srcRec:RRectangle, dstRec:RRectangle, tint:RColor)="ImageDraw"
-	Function bmx_raylib_ImageDrawRectangle(dst:RImage Var, rec:RRectangle, color:RColor)="ImageDrawRectangle"
+	Function bmx_raylib_ImageDrawRectangle(dst:RImage Var, posX:Int, posY:Int, width:Int, height:Int, color:RColor)="ImageDrawRectangle"
 	Function bmx_raylib_ImageDrawRectangleLines(dst:RImage Var, rec:RRectangle, thick:Int, color:RColor)="ImageDrawRectangleLines"
 	Function bmx_raylib_ImageDrawText(dst:RImage Var, position:RVector2, txt:Byte Ptr, FontSize:Int, color:RColor)="ImageDrawText"
 	Function bmx_raylib_ImageDrawTextEx(dst:RImage Var, position:RVector2, font:RFont, txt:Byte Ptr, FontSize:Float, spacing:Float, color:RColor)="ImageDrawTextEx"
@@ -422,6 +423,16 @@ Extern
 	Function bmx_raylib_GetDroppedFiles:Byte Ptr Ptr(count:Int Var)="GetDroppedFiles"
 	Function bmx_raylib_ClearDroppedFiles()="ClearDroppedFiles"
 
+	Function bmx_raylib_ImageClearBackground(dst:RImage, color:RColor)="ImageClearBackground"
+	Function bmx_raylib_ImageDrawPixel(dst:RImage, posX:Int, posY:Int, color:RColor)="ImageDrawPixel"
+	Function bmx_raylib_ImageDrawPixelV(dst:RImage, position:RVector2, color:RColor)="ImageDrawPixelV"
+	Function bmx_raylib_ImageDrawLine(dst:RImage, startPosX:Int, startPosY:Int, endPosX:Int, endPosY:Int, color:RColor)="ImageDrawLine"
+	Function bmx_raylib_ImageDrawLineV(dst:RImage, lineStart:RVector2, lineEnd:RVector2, color:RColor)="ImageDrawLineV"
+	Function bmx_raylib_ImageDrawCircle(dst:RImage, centerX:Int, centerY:Int, radius:Int, color:RColor)="ImageDrawCircle"
+	Function bmx_raylib_ImageDrawCircleV(dst:RImage, center:RVector2, radius:Int, color:RColor)="ImageDrawCircleV"
+	Function bmx_raylib_ImageDrawRectangleV(dst:RImage, position:RVector2, size:RVector2, color:RColor)="ImageDrawRectangleV"
+	Function bmx_raylib_ImageDrawRectangleRec(dst:RImage, rec:RRectangle, color:RColor)="ImageDrawRectangleRec"
+
 End Extern
 
 

+ 77 - 3
lib.mod/lib.bmx

@@ -26,11 +26,13 @@ bbdoc: Raylib - Simple Games Programming
 End Rem
 Module Ray.Lib
 
-ModuleInfo "Version: 1.01"
+ModuleInfo "Version: 1.02"
 ModuleInfo "License: zlib"
 ModuleInfo "Copyright: Wrapper - 2020 Bruce A Henderson"
 ModuleInfo "Copyright: raylib - 2013-2020 Ramon Santamaria"
 
+ModuleInfo "History: 1.02"
+ModuleInfo "History: Updated to raylib 3.0.7ef114d."
 ModuleInfo "History: 1.01"
 ModuleInfo "History: Updated to raylib 3.0.cb4c676."
 ModuleInfo "History: 1.00"
@@ -119,6 +121,13 @@ Function IsWindowHidden:Int()
 	Return bmx_raylib_IsWindowHidden()
 End Function
 
+Rem
+bbdoc: Checks if window is currently fullscreen
+End Rem
+Function IsWindowFullscreen:Int()
+	Return bmx_raylib_IsWindowFullscreen()
+End Function
+
 Rem
 bbdoc: Toggles fullscreen mode (only Desktop)
 End Rem
@@ -2247,8 +2256,8 @@ End Function
 Rem
 bbdoc: Draws a rectangle within an image.
 End Rem
-Function ImageDrawRectangle(dst:RImage Var, rec:RRectangle, color:RColor)
-	bmx_raylib_ImageDrawRectangle(dst, rec, color)
+Function ImageDrawRectangle(dst:RImage Var, posX:Int, posY:Int, width:Int, height:Int, color:RColor)
+	bmx_raylib_ImageDrawRectangle(dst, posX, posY, width, height, color)
 End Function
 
 Rem
@@ -2619,3 +2628,68 @@ Function GetDroppedFiles:String[]()
 	Return files
 End Function
 
+' Image drawing functions
+' NOTE: Image software-rendering functions (CPU)
+
+Rem
+bbdoc: Clears image background with given color.
+End Rem
+Function ImageClearBackground(dst:RImage, color:RColor)
+	bmx_raylib_ImageClearBackground(dst, color)
+End Function
+
+Rem
+bbdoc: Draws pixel within an image.
+End Rem
+Function ImageDrawPixel(dst:RImage, posX:Int, posY:Int, color:RColor)
+	bmx_raylib_ImageDrawPixel(dst, posX, posY, color)
+End Function
+
+Rem
+bbdoc: Draws pixel within an image (Vector version).
+End Rem
+Function ImageDrawPixelV(dst:RImage, position:RVector2, color:RColor)
+	bmx_raylib_ImageDrawPixelV(dst, position, color)
+End Function
+
+Rem
+bbdoc: Draws line within an image.
+End Rem
+Function ImageDrawLine(dst:RImage, startPosX:Int, startPosY:Int, endPosX:Int, endPosY:Int, color:RColor)
+	bmx_raylib_ImageDrawLine(dst, startPosX, startPosY, endPosX, endPosY, color)
+End Function
+
+Rem
+bbdoc: Draws line within an image (Vector version).
+End Rem
+Function ImageDrawLineV(dst:RImage, lineStart:RVector2, lineEnd:RVector2, color:RColor)
+	bmx_raylib_ImageDrawLineV(dst, lineStart, lineEnd, color)
+End Function
+
+Rem
+bbdoc: Draws circle within an image.
+End Rem
+Function ImageDrawCircle(dst:RImage, centerX:Int, centerY:Int, radius:Int, color:RColor)
+	bmx_raylib_ImageDrawCircle(dst, centerX, centerY, radius, color)
+End Function
+
+Rem
+bbdoc: Draws circle within an image (Vector version).
+End Rem
+Function ImageDrawCircleV(dst:RImage, center:RVector2, radius:Int, color:RColor)
+	bmx_raylib_ImageDrawCircleV(dst, center, radius, color)
+End Function
+
+Rem
+bbdoc: Draws rectangle within an image (Vector version).
+End Rem
+Function ImageDrawRectangleV(dst:RImage, position:RVector2, size:RVector2, color:RColor)
+	bmx_raylib_ImageDrawRectangleV(dst, position, size, color)
+End Function
+
+Rem
+bbdoc: Draws rectangle within an image.
+End Rem
+Function ImageDrawRectangleRec(dst:RImage, rec:RRectangle, color:RColor)
+	bmx_raylib_ImageDrawRectangleRec(dst, rec, color)
+End Function

+ 1 - 24
lib.mod/raylib/.gitignore

@@ -30,6 +30,7 @@ Thumbs.db
 *.cache
 *.ilk
 *.log
+.vs
 
 [Bb]in
 [Dd]ebug/
@@ -54,7 +55,6 @@ packages/
 *.a
 *.bc
 *.so
-!raylib.rc.o
 
 # Ignore all examples files
 examples/*
@@ -76,7 +76,6 @@ games/*
 !games/*/
 # Unignore all games files with extension
 !games/*.c
-!games/*.lua
 !games/*.png
 # Unignore games makefile
 !games/Makefile
@@ -96,23 +95,6 @@ xcschememanagement.plist
 xcuserdata/
 DerivedData/
 
-# Visual Studio project
-project/VS2015.UWP/packages
-project/VS2017/packages
-
-# Web examples
-docs/examples/web/*.html
-docs/examples/web/*/*.html
-!docs/examples/web/loader.html
-!docs/examples/web/core/loader.html
-!docs/examples/web/shapes/loader.html
-!docs/examples/web/text/loader.html
-!docs/examples/web/textures/loader.html
-!docs/examples/web/audio/loader.html
-!docs/examples/web/physac/loader.html
-!docs/examples/web/shaders/loader.html
-!docs/examples/web/models/loader.html
-
 # Jetbrains project
 .idea/
 cmake-build-debug/
@@ -128,17 +110,12 @@ install_manifest.txt
 compile_commands.json
 CTestTestfile.cmake
 build
-!templates/android_project/Makefile
 
 # Unignore These makefiles...
 !examples/CMakeLists.txt
 !games/CMakeLists.txt
 
-# Ignore Android generated files and folders
-templates/android_project/output
-
 # Ignore GNU global tags
 GPATH
 GRTAGS
 GTAGS
-.vs

+ 10 - 1
lib.mod/raylib/BINDINGS.md

@@ -17,6 +17,9 @@ Some people ported raylib to other languages in form of bindings or wrappers to
 | raylib-lua         | Lua            | https://github.com/raysan5/raylib-lua                                |
 | raylib-lua-ffi     | Lua            | https://github.com/raysan5/raylib/issues/693                         |
 | raylib-lua-sol     | Lua            | https://github.com/RobLoach/raylib-lua-sol                           |
+| raylib-lua (raylua)| Lua            | https://github.com/TSnake41/raylib-lua                               |
+| raylib-luamore     | Lua            | https://github.com/HDPLocust/raylib-luamore                          |
+| raylib-nelua       | Nelua          | https://github.com/Andre-LA/raylib-nelua-mirror                      |
 | raylib-Nim         | Nim            | https://gitlab.com/define-private-public/raylib-Nim                  |
 | raylib-nim         | Nim            | https://github.com/Skrylar/raylib-nim                                |
 | raylib-haskell     | Haskell        | https://github.com/DevJac/raylib-haskell                             |
@@ -50,12 +53,18 @@ Some people ported raylib to other languages in form of bindings or wrappers to
 | Euraylib           | Euphoria       | https://github.com/gAndy50/Euraylib                                  |
 | raylib-wren        | Wren           | https://github.com/TSnake41/raylib-wren                              |
 | raylib-odin        | Odin           | https://github.com/kevinw/raylib-odin                                |
+| raylib-zig         | Zig            | https://github.com/G3bE/raylib-zig                   |
 | ray.zig            | Zig            | https://github.com/BitPuffin/zig-raylib-experiments                  |
 | raylib-Ada         | Ada            | https://github.com/mimo/raylib-Ada                                   |
 | jaylib             | Janet          | https://github.com/janet-lang/jaylib                                 |
 | raykit             | Kit            | https://github.com/Gamerfiend/raykit                                 |
 | vraylib            | V              | https://github.com/MajorHard/vraylib                                 |
-| ray.mod            | BlitzMax       | https://github.com/bmx-ng/ray.mod  |
+| ray.mod            | BlitzMax       | https://github.com/bmx-ng/ray.mod                    |
+| raylib-mosaic      | Mosaic         | https://github.com/pluckyporcupine/raylib-mosaic     |
+| raylib-xdpw        | XD Pascal      | https://github.com/vtereshkov/raylib-xdpw            |
+| raylib-carp        | Carp           | https://github.com/pluckyporcupine/raylib-carp       |
+| raylib-fb          | FreeBasic      | https://github.com/IchMagBier/raylib-fb              |
+| raylib-ats2        | ATS2           | https://github.com/mephistopheles-8/raylib-ats2      |
 | raylib.cbl         | COBOL          | *[code examples](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)* |
  
 Missing some language? Check the [bindings not yet in this list](https://gist.github.com/raysan5/5764cc5b885183f523fce47f098f3d9b#bindings-not-yet-in-the-official-list) or create a new binding! :)

+ 28 - 7
lib.mod/raylib/CHANGELOG

@@ -1,18 +1,20 @@
 changelog
 ---------
 
-Current Release:    raylib 3.0.0 (Feb.2020) -WIP-
+Current Release:    raylib 3.0.0 (01 April 2020)
 
 -----------------------------------------------
-Release:     raylib 3.0 (Feb 2020)
+Release:     raylib 3.0 (01 April 2020)
 -----------------------------------------------
 KEY CHANGES:
  - Global context states used on all modules. 
  - Custom memory allocators for all modules and dependencies.
- - Structures reviewed to reduce size and always used as pass-by-value.
+ - Centralized file access system and memory data loading.
+ - Structures reviewed to reduce size and always be used as pass-by-value.
+ - Tracelog messages completely reviewed and categorized.
  - raudio module reviewed to accomodate new Music struct and new miniaudio.
  - text module reviewed to improve fonts generation and text management functions.
- - examples addition, multiple new examples and categorized examples table.
+ - Multiple new examples added and categorized examples table.
  - GitHub Actions CI implemented for Windows, Linux and macOS.
  
 Detailed changes:
@@ -28,13 +30,11 @@ Detailed changes:
 [build] REVIEWED: Generation of web examples, by @pamarcos
 [build] REVIEWED: Makefiles path to 'shell.html', by @niorad
 [build] REVIEWED: VS2017 64bit compilation issues, by @spec-chum
-[build] REVIEWED: Multiple fixes on projkects building, by @ChrisDill, @JuDelCo, @electronstudio
+[build] REVIEWED: Multiple fixes on projects building, by @ChrisDill, @JuDelCo, @electronstudio
 [core] ADDED: Support touch/mouse indistinctly
 [core] ADDED: FLAG_WINDOW_ALWAYS_RUN to avoid pause on minimize
 [core] ADDED: Config flag SUPPORT_HALFBUSY_WAIT_LOOP
 [core] ADDED: RPI mouse cursor point support on native mode
-[core] ADDED: BeginScissorMode() - Define screen area for following drawing
-[core] ADDED: EndScissorMode() - End scissor mode
 [core] ADDED: GetWorldToScreen2D()- Get screen space position for a 2d camera world space position, by @arvyy
 [core] ADDED: GetScreenToWorld2D() - Get world space position for a 2d camera screen space position, by @arvyy
 [core] ADDED: GetWorldToScreenEx() - Get size position for a 3d world space position
@@ -43,8 +43,14 @@ Detailed changes:
 [core] ADDED: CompressData() - Compress data (DEFLATE algorythm)
 [core] ADDED: DecompressData() - Decompress data (DEFLATE algorythm)
 [core] ADDED: GetWindowPosition() - Get window position XY on monitor
+[core] ADDED: LoadFileData() - Load file data as byte array (read)
+[core] ADDED: SaveFileData() - Save data to file from byte array (write)
+[core] ADDED: LoadFileText() - Load text data from file (read), returns a '\0' terminated string
+[core] ADDED: SaveFileText() - Save text data to file (write), string must be '\0' terminated
 [core] REMOVED: Show raylib logo at initialization
 [core] REVIEWED: GetFileName(), security checks
+[core] REVIEWED: LoadStorageValue(), by @danimartin82
+[core] REVIEWED: SaveStorageValue(), by @danimartin82
 [core] REVIEWED: IsMouseButtonReleased(), when press/release events come too fast, by @oswjk
 [core] REVIEWED: SetWindowMonitor(), by @DropsOfSerenity
 [core] REVIEWED: IsFileExtension() to be case-insensitive
@@ -81,6 +87,19 @@ Detailed changes:
 [textures] ADDED: LoadAnimatedGIF() - Load animated GIF file
 [textures] ADDED: GetImageAlphaBorder() - Get image alpha border rectangle
 [textures] ADDED: ImageFromImage() - Create an image from another image piece
+[textures] ADDED: ImageClearBackground(), by @iamsouravgupta
+[textures] ADDED: ImageDrawPixel(), by @iamsouravgupta
+[textures] ADDED: ImageDrawCircle(), by @iamsouravgupta
+[textures] ADDED: ImageDrawLineEx(), by @iamsouravgupta
+[textures] ADDED: ImageDrawPixelV(), by @RobLoach
+[textures] ADDED: ImageDrawCircleV(), by @RobLoach
+[textures] ADDED: ImageDrawLineV(), by @RobLoach
+[textures] ADDED: ImageDrawRectangleV(), by @RobLoach
+[textures] ADDED: ImageDrawRectangleRec(), by @RobLoach
+[textures] REVIEWED: ImageDrawPixel(), by @RobLoach
+[textures] REVIEWED: ImageDrawLine(), by @RobLoach
+[textures] REVIEWED: ImageDrawCircle(), by @RobLoach
+[textures] REVIEWED: ImageDrawRectangle(), by @RobLoach
 [textures] REVIEWED: ImageDraw(), now it supports color tint parameter
 [textures] REVIEWED: ImageResizeCanvas()
 [textures] REVIEWED: ImageCrop() with security checks
@@ -134,6 +153,7 @@ Detailed changes:
 [examples] ADDED: shaders_basic_lighting, by @chriscamacho
 [examples] ADDED: shaders_simple_mask, by @chriscamacho
 [examples] ADDED: audio_multichannel_sound, by @chriscamacho
+[examples] ADDED: shaders_spotlight, by @chriscamacho
 [examples] RENAMED: text_sprite_font > text_font_spritefont
 [examples] RENAMED: text_ttf_loading > text_font_filters
 [examples] RENAMED: text_bmfont_ttf > text_font_loading
@@ -142,6 +162,7 @@ Detailed changes:
 [examples] REVIEWED: models_obj_loading > models_loading
 [examples] REVIEWED: models_materials_pbr, shader issues
 [examples] REVIEWED: core_window_letterbox, detailed explanation, by @jotac0
+[examples] REVIEWED: core_window_letterbox, virtual mouse, by @anatagawa
 [games] ADDED: GGJ2020 game - RE-PAIR
 [*] Misc fixes and tweaks, by @yaram, @oraoto, @zatherz, @piecedigital, @Shylie
 [*] Update ALL supported projects (Notepad++, VS2017)

+ 6 - 6
lib.mod/raylib/CONTRIBUTING.md

@@ -6,8 +6,8 @@ Do you enjoy raylib and want to contribute? Nice! You can help with the followin
 
 - C programming - Can you write/review/test/improve the code? 
 - Documentation/Tutorials/Example - Can you write some tutorial/example?
-- Web Development - Can you help [with the website](https://github.com/raysan5/raylib.com)?
 - Porting to other platforms - Can you port and compile raylib on other systems?
+- Web Development - Can you help [with the website](https://github.com/raysan5/raylib.com)?
 - Testing - Can you find some bugs in raylib?
 
 This document contains a set of guidelines to contribute to the project. These are mostly guidelines, not rules. 
@@ -16,10 +16,10 @@ Use your best judgement, and feel free to propose changes to this document in a
 ### raylib philosophy
 
  - raylib is a tool to enjoy videogames programming, every single function in raylib should be a tutorial on itself.
- - raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or is not clearly useful, better not to include it.
- - raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free.
+ - raylib is **SIMPLE** and **EASY-TO-USE**, I tried to keep it compact with a small set of functions, if a function is too complex or is not clearly useful, better not including it.
+ - raylib is open source and free; educators and institutions can use this tool to **TEACH** videogames programming completely for free.
  - raylib is collaborative; contribution of tutorials / code examples / bug fixes / code comments are highly appreciated.
- - raylib's license (and its external libs respective licenses) allow using it for commercial products.
+ - raylib's license (and its external libs respective licenses) allow using it on commercial projects.
 
 ### Some interesting reads to start with
 
@@ -36,7 +36,7 @@ Feel free to review it if required, just take care not to break something.
 Despite being written in C, raylib does not follow the standard Hungarian notation for C, 
 it [follows Pascal-case/camel-case notation](https://github.com/raysan5/raylib/wiki/raylib-coding-conventions), 
 more common on C# language. All code formatting decisions have been carefully taken
-to make it easier for students to read, write and understand code. 
+to make it easier for students/users to read, write and understand code.
 
 Source code is extensively commented for that purpose, raylib primary learning method is:
 
@@ -133,4 +133,4 @@ contributing (in some way or another) to make the raylib project better. Huge th
  - [PompPenguin](https://github.com/PompPenguin) for reviewing 3rd person camera
  - [Mohamed Shazan](https://github.com/msmshazan) for adding support for ANGLE graphics backend
  
-Please, if I forget someone in this list, excuse me and send a PR!
+Please, if I forget someone in this list, excuse me and send me a PR!

+ 89 - 60
lib.mod/raylib/HISTORY.md

@@ -1,19 +1,19 @@
 ![raylib logo](logo/raylib_256x256.png)
 
-history
--------
+introduction
+------------
 
-I've developed videogames since 2006 and in 2012 I started teaching videogames development to young people with artistic profile, most of them had never written a single line of code.
+I started developing videogames in 2006 and some years later I started teaching videogames development to young people with artistic profile, most of students had never written a single line of code.
 
-I started with C language basis and, after searching for the most simple and easy-to-use library to teach videogames programming, I found WinBGI; it was great and it worked very well with students, in just a couple of weeks that people that had never written a single line of code were able to program (and understand) a simple PONG and some of them even a BREAKOUT!
+I decided to start with C language basis and, after searching for the most simple and easy-to-use library to teach videogames programming, I found [WinBGI](http://www.codecutter.net/tools/winbgim/); it was great and it worked very well with students, in just a couple of weeks, those students that had never written a single line of code were able to program (and understand) a simple PONG game, some of them even a BREAKOUT!
 
-But WinBGI was not the clearer and most organized lib. There were a lot of things I found confusing and some function names were not clear enough for most of the students; not to mention points like no transparencies support or no hardware acceleration.
+But WinBGI was not the clearer and most organized library for my taste. There were lots of things I found confusing and some function names were not clear enough for most of the students; not to mention the lack of transparencies support and no hardware acceleration.
 
 So, I decided to create my own library, hardware accelerated, clear function names, quite organized, well structured, plain C coding and, the most important, primarily intended to learn videogames programming.
 
-Most of my videogames coding experience was in C# and XNA and I really love it (in fact, my students learn C# after C), so, I decided to use C# language notation and XNA naming conventions. That way, students can jump from raylib to XNA, MonoGame or similar libs extremely easily.
+My previous videogames development experience was mostly in C# and [XNA](https://en.wikipedia.org/wiki/Microsoft_XNA) and I really loved it, so, I decided to use C# language style notation and XNA naming conventions. That way, students were able to move from raylib to XNA, MonoGame or similar libs extremely easily.
 
-raylib started as a weekend project and after three months of hard work, raylib 1.0 was published on November 2013.
+raylib started as a weekend project and after three months of hard work, **raylib 1.0 was published on November 2013**.
 
 Enjoy it.
 
@@ -22,9 +22,9 @@ notes on raylib 1.1
 
 On April 2014, after 6 month of first raylib release, raylib 1.1 has been released. This new version presents a complete internal redesign of the library to support OpenGL 1.1, OpenGL 3.3+ and OpenGL ES 2.0.
 
-A new module named [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translates raylib-OpenGL-style immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define.
+ - A new module named [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translates raylib-OpenGL-style immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define.
 
-[rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes a bunch of useful functions for 3d-math with vectors, matrices and quaternions.
+ - [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes a bunch of useful functions for 3d-math with vectors, matrices and quaternions.
 
 Some other big changes of this new version have been the support for OGG files loading and stream playing, and the support of DDS texture files (compressed and uncompressed) along with mipmaps support.
 
@@ -37,9 +37,9 @@ On September 2014, after 5 month of raylib 1.1 release, it comes raylib 1.2. Aga
 
 It's been some month of really hard work to accomodate raylib to those new platforms while keeping it easy for the users. On Android, raylib manages internally the activity cicle, as well as the inputs; on Raspberry Pi, a complete raw input system has been written from scratch.
 
-A new display initialization system has been created to support multiple resolutions, adding black bars if required; user only defines desired screen size and it gets properly displayed.
+ - A new display initialization system has been created to support multiple resolutions, adding black bars if required; user only defines desired screen size and it gets properly displayed.
 
-Now raylib can easily deploy games to Android devices and Raspberry Pi (console mode).
+ - Now raylib can easily deploy games to Android devices and Raspberry Pi (console mode).
 
 Lots of code changes and lot of testing have concluded in this amazing new raylib 1.2.
 
@@ -50,15 +50,15 @@ notes on raylib 1.3
 
 On September 2015, after 1 year of raylib 1.2 release, arrives raylib 1.3. This version adds shaders functionality, improves tremendously textures module and also provides some new modules (camera system, gestures system, immediate-mode gui).
 
-Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen postrocessing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder.
+ - Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen postrocessing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder.
 
-Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files. 
+ - Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files. 
 
-A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/camera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_first_person.c).
+ - A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/camera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_first_person.c).
 
-New [gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.h) module simplifies gestures detection on Android and HTML5 programs.
+ - New [gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.h) module simplifies gestures detection on Android and HTML5 programs.
 
-[raygui](https://github.com/raysan5/raylib/blob/master/src/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primary intended for tools development. It's still in experimental state but already fully functional.
+ - [raygui](https://github.com/raysan5/raylib/blob/master/src/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primary intended for tools development. It's still in experimental state but already fully functional.
 
 Most of the examples have been completely rewritten and +10 new examples have been added to show the new raylib features.
 
@@ -69,17 +69,17 @@ notes on raylib 1.4
 
 On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added.
 
-First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage.
+ - First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage.
 
-SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file.
+ - SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file.
 
-New [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) physics module for basic 2D physics support. Still in development but already functional. Module comes with some usage examples for basic jump and level interaction and also force-based physic movements.
+ - New [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) physics module for basic 2D physics support. Still in development but already functional. Module comes with some usage examples for basic jump and level interaction and also force-based physic movements.
 
-[raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline. 
+ - [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline. 
 
-[gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code.
+ - [gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code.
 
-Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental).
+ - Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental).
 
 Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions, 
 and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported). A simple [easings](https://github.com/raysan5/raylib/blob/master/src/easings.h) module has also been added for values animation.
@@ -94,17 +94,17 @@ notes on raylib 1.5
 
 On July 2016, after 5 months of raylib 1.4 release, arrives raylib 1.5. This new version is the biggest boost of the library until now, lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added.
 
-VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c).
+ - VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c).
 
-New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally.
+ - New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally.
 
-New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages render internally for every 3d object using standard material.
+ - New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages render internally for every 3d object using standard material.
 
-Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread.
+ - Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread.
 
-Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread.
+ - Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread.
 
-Audio chiptunese support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All this features thanks to the amazing work of @kd7tck.
+ - Audio chiptunese support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All this features thanks to the amazing work of @kd7tck.
 
 Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/master/examples/core_2d_camera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/master/examples/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms.
 
@@ -119,17 +119,17 @@ notes on raylib 1.6
 
 On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version conmmemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features:
 
-Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
+ - Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
 
-Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
+ - Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
 
-[Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
+ - [Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
 
-Camera and gestures modules have been reviewed, highly simplified and ported to single-file header-only libraries for easier portability and usage flexibility. Consequently, camera system usage has been simplified in all examples.
+ - Camera and gestures modules have been reviewed, highly simplified and ported to single-file header-only libraries for easier portability and usage flexibility. Consequently, camera system usage has been simplified in all examples.
 
-Improved Gamepad support on Windows and Raspberry Pi with the addition of new functions for custom gamepad configurations but supporting by default PS3 and Xbox-based gamepads.
+ - Improved Gamepad support on Windows and Raspberry Pi with the addition of new functions for custom gamepad configurations but supporting by default PS3 and Xbox-based gamepads.
 
-Improved textures and text functionality, adding new functions for texture filtering control and better TTF/AngelCode fonts loading and generation support.
+ - Improved textures and text functionality, adding new functions for texture filtering control and better TTF/AngelCode fonts loading and generation support.
 
 Build system improvement. Added support for raylib dynamic library generation (raylib.dll) for users that prefer dynamic library linking. Also thinking on advance users, it has been added pre-configured [Visual Studio C++ 2015 solution](https://github.com/raysan5/raylib/tree/master/project/vs2015) with raylib project and C/C++ examples for users that prefer that professional IDE and compiler.
 
@@ -140,15 +140,15 @@ notes on raylib 1.7
 
 On May 2017, around 6 month after raylib 1.6, comes another raylib instalment, raylib 1.7. This time library has been improved a lot in terms of consistency and cleanness. As stated in [this patreon article](https://www.patreon.com/posts/raylib-future-7501034), this new raylib version has focused efforts in becoming more simple and easy-to-use to learn videogames programming. Some highlights of this new version are:
 
-More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, funtions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions!
+ - More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, funtions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions!
 
-Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advance users can customize raylib just choosing desired features, defining some configuration flags on modules compilation. That way users can control library size and available functionality.
+ - Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advance users can customize raylib just choosing desired features, defining some configuration flags on modules compilation. That way users can control library size and available functionality.
 
-Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compliation flags.
+ - Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compliation flags.
 
-New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All samples material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to latest raylib version and tested in multiple platforms. Examples folder structure has been improved and also build systems.
+ - New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All samples material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to latest raylib version and tested in multiple platforms. Examples folder structure has been improved and also build systems.
 
-Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplyfied, some functions has been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process...
+ - Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplyfied, some functions has been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process...
 
 Some other features: Gamepad support on HTML5, RPI touch screen support, 32bit audio support, frames timing improvements, public log system, rres file format support, automatic GIF recording...
 
@@ -159,17 +159,17 @@ notes on raylib 1.8
 
 October 2017, around 5 months after latest raylib version, another release is published: raylib 1.8. Again, several modules of the library have been reviewed and some new functionality added. Main changes of this new release are:
 
-[Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses.
+ - [Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses.
 
-[Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing.
+ - [Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing.
 
-PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference.
+ - PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference.
 
-Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts.
+ - Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts.
 
-[rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions.
+ - [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions.
 
-[raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) library has been also reviewed to align with other advance math libraries like [GLM](https://github.com/g-truc/glm). Matrix math has been improved and simplified, some new Quaternion functions have been added and Vector3 functions have been renamed all around the library for consistency with new Vector2 functionality.
+ - [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) library has been also reviewed to align with other advance math libraries like [GLM](https://github.com/g-truc/glm). Matrix math has been improved and simplified, some new Quaternion functions have been added and Vector3 functions have been renamed all around the library for consistency with new Vector2 functionality.
 
 Additionally, as always, examples and templates have been reviewed to work with new version (some new examples have been added), all external libraries have been updated to latest stable version and latest Notepad++ and MinGW have been configured to work with new raylib. For a full list of changes, just check [CHANGELOG](CHANGELOG).
 
@@ -182,17 +182,17 @@ It's been 9 month since last raylib version was published, a lots of things have
 
 In **raylib 2.0** the full API has been carefully reviewed for better consistency, some new functionality has been added and the overall raylib experience has been greatly improved... The key features of new version are:
 
-**Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependant ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library. 
+ - **Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependant ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library. 
 
-**Full redesign of audio module to use the amazing miniaudio library**, along with external dependencies removal, OpenAL library has been replaced by [miniaudio](https://github.com/dr-soft/miniaudio), this brand new library offers automatic dynamic linking with default OS audio systems. Undoubtly, the perfect low-level companion for raylib audio module!
+ - **Full redesign of audio module to use the amazing miniaudio library**, along with external dependencies removal, OpenAL library has been replaced by [miniaudio](https://github.com/dr-soft/miniaudio), this brand new library offers automatic dynamic linking with default OS audio systems. Undoubtly, the perfect low-level companion for raylib audio module!
 
-**Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplyfing the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release!
+ - **Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplyfing the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release!
 
-**More platforms supported and tested**, including BSD family (FreeBSD, openBSD, NetBSD, DragonFly) and Linux-based family platforms (openSUSE, Debian, Ubuntu, Arch, NixOS...). raylib has already been added to some package managers! Oh, and last but not less important, **Android 64bit** is already supported by raylib!
+ - **More platforms supported and tested**, including BSD family (FreeBSD, openBSD, NetBSD, DragonFly) and Linux-based family platforms (openSUSE, Debian, Ubuntu, Arch, NixOS...). raylib has already been added to some package managers! Oh, and last but not less important, **Android 64bit** is already supported by raylib!
 
-**Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provide by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds!
+ - **Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provide by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds!
 
-Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file-formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired!
+ - Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file-formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired!
 
 A part of that, lots of new features, like a brand **new font rendering and packaging system** for TTF fonts with **SDF support** (thanks to the amazing STB headers), new functions for **CPU image data manipulation**, new orthographic 3d camera mode, a complete review of `raymath.h` single-file header-only library for better consistency and performance, new examples and way, [way more](https://github.com/raysan5/raylib/blob/master/CHANGELOG).
 
@@ -203,25 +203,54 @@ notes on raylib 2.5
 
 After almost one years since latest raylib installment, here it is **raylib 2.5**. A lot of work has been put on this new version and consequently I decided to bump versioning several digits. The complete list of changes and additions is humungous, details can be found in the [CHANGELOG](CHANGELOG), and here it is a short recap with the highlight improvements.
 
-New **window management and filesystem functions** to query monitor information, deal with clipboard, check directory files info and even launch a URL with default system web browser. Experimental **High-DPI monitor support** has also been added through a compile flag.
+ - New **window management and file system functions** to query monitor information, deal with clipboard, check directory files info and even launch a URL with default system web browser. Experimental **High-DPI monitor support** has also been added through a compile flag.
 
-**Redesigned Gamepad mechanism**, now generic for all platforms and gamepads, no more specific gamepad configurations.
+ - **Redesigned Gamepad mechanism**, now generic for all platforms and gamepads, no more specific gamepad configurations.
 **Redesigned UWP input system**, now raylib supports UWP seamlessly, previous implementation required a custom input system implemented in user code.
 
-`rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behaviour.
+ - `rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behaviour.
 
-**VR simulator** has been reviewed to **allow custom configuration of Head-Mounted-Device parameters and distortion shader**, `core_vr_simulator` has been properly adapted to showcase this new functionality, now the VR simulator is a generic configurable stereo rendering system that allows any VR device simulation with just a few lines of code or even dynamic tweaking of HMD parameters.
+ - **VR simulator** has been reviewed to **allow custom configuration of Head-Mounted-Device parameters and distortion shader**, `core_vr_simulator` has been properly adapted to showcase this new functionality, now the VR simulator is a generic configurable stereo rendering system that allows any VR device simulation with just a few lines of code or even dynamic tweaking of HMD parameters.
 
-Support for **Unicode text drawing**; now raylib processes UTF8 strings on drawing, supporting Unicode codepoints, allowing rendering mostly any existent language (as long as the font with the glyphs is provided). An amazing example showing this feature has also been added: `text_unicode`.
+ - Support for **Unicode text drawing**; now raylib processes UTF8 strings on drawing, supporting Unicode codepoints, allowing rendering mostly any existent language (as long as the font with the glyphs is provided). An amazing example showing this feature has also been added: `text_unicode`.
 
-Brand **new text management API**, with the addition of multiple functions to deal with string data, including functionality like replace, insert, join, split, append, to uppercase, to lower... Note that most of those functions are intended for text management on rendering, using pre-loaded internal buffers, avoiding new memory allocation that user should free manually.
+ - Brand **new text management API**, with the addition of multiple functions to deal with string data, including functionality like replace, insert, join, split, append, to uppercase, to lower... Note that most of those functions are intended for text management on rendering, using pre-loaded internal buffers, avoiding new memory allocation that user should free manually.
 
-Multiple **new shapes and textures drawing functions** to support rings (`DrawRing()`, `DrawRingLines()`), circle sectors (`DrawCircleSector()`, `DrawCircleSectorLines()`), rounded rectangles (`DrawRectangleRounded()`, `DrawRectangleRoundedLines()`) and also n-patch textures (`DrawTextureNPatch()`), detailed examples have been added to illustrate all this new functionality. 
+ - Multiple **new shapes and textures drawing functions** to support rings (`DrawRing()`, `DrawRingLines()`), circle sectors (`DrawCircleSector()`, `DrawCircleSectorLines()`), rounded rectangles (`DrawRectangleRounded()`, `DrawRectangleRoundedLines()`) and also n-patch textures (`DrawTextureNPatch()`), detailed examples have been added to illustrate all this new functionality. 
 
-Experimental **cubemap support**, to automatically load multiple cubemap layouts (`LoadTextureCubemap()`). It required some internal `rlgl` redesign to allow cubemap textures.
+ - Experimental **cubemap support**, to automatically load multiple cubemap layouts (`LoadTextureCubemap()`). It required some internal `rlgl` redesign to allow cubemap textures.
 
-**Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accomodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added.
+ - **Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accomodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added.
 
 This is a just a brief list with some of the changes of the new **raylib 2.5** but there is way more, about **70 new functions** have been added and several subsystems have been redesigned. More than **30 new examples** have been created to show the new functionalities and better illustrate already available ones.
 
 It has been a long year of hard work to make raylib a solid technology to develop new products over it.
+
+notes on raylib 3.0
+-------------------
+
+After **10 months of intense development**, new raylib version is ready. Despite primary intended as a minor release, the [CHANGELIST](CHANGELOG) has grown so big and the library has changed so much internally that it finally became a major release. Library **internal ABI** has reveived a big redesign and review, targeting portability, integration with other platforms and making it a perfect option for other progamming [language bindings](BINDINGS.md).
+
+ - All **global variables** from the multiple raylib modules have been moved to a **global context state**, it has several benefits, first, better code readability with more comprehensive variables naming and categorization (organized by types, i.e. `CORE.Window.display.width`, `CORE.Input.Keyboard.currentKeyState` or `RLGL.State.modelview`). Second, it allows better memory management to load global context state dynamically when required (not at the moment), making it easy to implement a **hot-reloading mechanism** if desired.
+
+ - All **memory allocations** on raylib and its dependencies now use `RL_MALLOC`, `RL_FREE` and similar macros. Now users can easely hook their own memory allocations mechanism if desired, having more control over memory allocated internally by the library. Additionally, it makes it easier to port the library to embedded devices where memory control is critical. For more info check raylib issue #1074.
+
+ - All **I/O file accesses** from raylib are being moved to **memory data access**, now all I/O file access is centralized into just four functions: `LoadFileData()`, `SaveFileData()`, `LoadFileText()`, `SaveFileText()`. Users can just update those functions to any I/O file system. This change makes it easier to integrate raylib with **Virtual File Systems** or custom I/O file implementations.
+
+ - All **raylib data structures** have been reviewed and optimized for pass-by-value usage. One of raylib distinctive design decisions is that most of its functions receive and return data by value. This design makes raylib really simple for newcomers, avoiding pointers and allowing complete access to all structures data in a simple way. The downside is that data is copied on stack every function call and that copy could be costly so, all raylib data structures have been optimized to **stay under 64 bytes** for fast copy and retrieve.
+
+ - All **raylib tracelog messages** have been reviewd and categorized for a more comprehensive output information when developing raylib applications, now all display, input, timer, platform, auxiliar libraries, file-accesses, data loading/unloading issues are properly reported with more detailed and visual messages.
+
+ - `raudio` module has been internally reviewed to accomodate the new `Music` structure (converted from previous pointer format) and the module has been adapted to the **highly improved** [`miniaudio v0.10`](https://github.com/dr-soft/miniaudio).
+
+ - `text` module reviewed to **improve fonts generation** and text management functions, `Font` structure has been redesigned to better accomodate characters data, decoupling individual characters as `Image` glyphs from the font atlas parameters. Several improvements have been made to better support Unicode strings with UTF-8 encoding.
+
+ - **Multiple new examples added** (most of them contributed by raylib users) and all examples reviewed for correct execution on most of the supported platforms, specially Web and Raspberry Pi. A detailed categorized table has been created on github for easy examples navigation and code access.
+
+ - New **GitHub Actions CI** system has been implemented for Windows, Linux and macOS code and examples compilation on every new commit or PR to make sure library keeps stable and usable with no breaking bugs.
+
+Note that only key changes are listed here but there is way more! About **30 new functions**, multiple functions reviewed, bindings to [+40 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md) and great samples/demos/tutorials [created by the community](https://discord.gg/VkzNHUE), including raylib integration with [Spine](https://github.com/WEREMSOFT/spine-raylib-runtimes), [Unity](https://unitycoder.com/blog/2019/12/09/using-raylib-dll-in-unity/), [Tiled](https://github.com/OnACoffeeBreak/raylib_tiled_import_with_tmx), [Nuklear](http://bedroomcoders.co.uk/implementing-a-3d-gui-with-raylib/), [enet](https://github.com/nxrighthere/NetDynamics) and [more](https://github.com/raysan5/raylib/issues/1079)!
+
+It has been **10 months of improvements** to create the best raylib ever.
+
+Welcome to **raylib 3.0**.

+ 59 - 19
lib.mod/raylib/README.md

@@ -8,11 +8,20 @@ raylib is highly inspired by Borland BGI graphics lib and by XNA framework and i
 
 Ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
 
-[![Build Status](https://travis-ci.org/raysan5/raylib.svg?branch=master)](https://travis-ci.org/raysan5/raylib)
-[![https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true](https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true)](https://ci.appveyor.com/project/raysan5/raylib)
-[![Chat on Discord](https://img.shields.io/discord/426912293134270465.svg?logo=discord)](https://discord.gg/VkzNHUE)
+<br>
+
+[![GitHub contributors](https://img.shields.io/github/contributors/raysan5/raylib)](https://github.com/raysan5/raylib/graphs/contributors)
+[![GitHub All Releases](https://img.shields.io/github/downloads/raysan5/raylib/total)](https://github.com/raysan5/raylib/releases)
+[![GitHub commits since tagged version](https://img.shields.io/github/commits-since/raysan5/raylib/2.6.0)](https://github.com/raysan5/raylib/commits/master)
 [![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE)
-[![Twitter URL](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Follow)](https://twitter.com/raysan5)
+
+[![Chat on Discord](https://img.shields.io/discord/426912293134270465.svg?logo=discord)](https://discord.gg/VkzNHUE)
+[![GitHub stars](https://img.shields.io/github/stars/raysan5/raylib?style=social)](https://github.com/raysan5/raylib/stargazers)
+[![Twitter Follow](https://img.shields.io/twitter/follow/raysan5?style=social)](https://twitter.com/raysan5)
+[![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/raylib?style=social)](https://www.reddit.com/r/raylib/)
+
+[![Travis (.org)](https://img.shields.io/travis/raysan5/raylib?label=Travis%20CI%20Build%20Status%20-%20Linux,%20OSX,%20Android,%20Windows)](https://travis-ci.org/raysan5/raylib)
+[![AppVeyor](https://img.shields.io/appveyor/build/raysan5/raylib?label=AppVeyor%20CI%20Build%20Status%20-%20Windows%20(mingw,%20msvc15))](https://ci.appveyor.com/project/raysan5/raylib)
 
 [![Actions Status](https://github.com/raysan5/raylib/workflows/CI%20-%20Source%20&%20Examples%20-%20Windows/badge.svg)](https://github.com/raysan5/raylib/actions)
 [![Actions Status](https://github.com/raysan5/raylib/workflows/CI%20-%20Source%20&%20Examples%20-%20Linux/badge.svg)](https://github.com/raysan5/raylib/actions)
@@ -21,46 +30,77 @@ Ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
 features
 --------
   - **NO external dependencies**, all required libraries are bundled into raylib
-  - Multiple platforms supported: **Windows, Linux, MacOS, Android... and many more!**
+  - Multiple platforms supported: **Windows, Linux, MacOS, Android, HTML5... and more!**
   - Written in plain C code (C99) in PascalCase/camelCase notation
   - Hardware accelerated with OpenGL (**1.1, 2.1, 3.3 or ES 2.0**)
   - **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
-  - Multiple **Fonts** formats supported (XNA fonts, AngelCode fonts, TTF)
+  - Multiple **Fonts** formats supported (TTF, XNA fonts, AngelCode fonts)
   - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
   - **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more! 
   - Flexible Materials system, supporting classic maps and **PBR maps**
   - **Animated 3D models** supported (skeletal bones animation)
-  - Shaders support, including model and postprocessing shaders.
+  - Shaders support, including model and **postprocessing** shaders.
   - **Powerful math module** for Vector, Matrix and Quaternion operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h)
   - Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
   - **VR stereo rendering** support with configurable HMD device parameters
-  - Huge examples collection with [+95 code examples](https://www.raylib.com/examples.html)!
-  - Bindings to [+25 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)!
-
+  - Huge examples collection with [+115 code examples](https://github.com/raysan5/raylib/tree/master/examples)!
+  - Bindings to [+40 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)!
+  - Free and open source.
 
 raylib uses on its [core](https://github.com/raysan5/raylib/blob/master/src/core.c) module the outstanding [GLFW3](http://www.glfw.org/) library, embedded in the form of [rglfw](https://github.com/raysan5/raylib/blob/master/src/rglfw.c) module, to avoid external dependencies.
 
 raylib uses on its [raudio](https://github.com/raysan5/raylib/blob/master/src/raudio.c) module, the amazing [miniaudio](https://github.com/dr-soft/miniaudio) library to support multiple platforms and multiple audio backends.
 
-raylib uses internally multiple single-file header-only libraries to support different fileformats loading and saving, all those libraries are embedded with raylib and available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory. Check [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies) for a detailed list.
+raylib uses internally several single-file header-only libraries to support different fileformats loading and saving, all those libraries are embedded with raylib and available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory. Check [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies) for a detailed list.
 
-*On Android platform, `native_app_glue module` module (provided by Android NDK) and native Android libraries are used to manage window/context, inputs and activity life cycle.*
+*On Android platform, `native_app_glue` module (provided by Android NDK) and native Android libraries are used to manage window/context, inputs and activity life cycle.*
 
 *On Raspberry Pi platform (native mode), `Videocore API` and `EGL` libraries are used for window/context management. Inputs are processed using `evdev` Linux libraries*
 
+*On Web platform, raylib uses `emscripten` provided libraries for several input events management, specially noticeable the touch events support.*
+
 build and installation
 ----------------------
 
-Binary releases for Windows, Linux and macOS are available at the [Github Releases page](https://github.com/raysan5/raylib/releases). raylib is also available via multiple package managers on multiple OS distributions. Check [raylib Wiki](https://github.com/raysan5/raylib/wiki) for more info.
+raylib binary releases for Windows, Linux and macOS are available at the [Github Releases page](https://github.com/raysan5/raylib/releases).
+
+raylib is also available via multiple [package managers](https://github.com/raysan5/raylib/issues/613) on multiple OS distributions.
+
+#### Installing and building raylib via vcpkg
+
+You can download and install raylib using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
+
+      git clone https://github.com/Microsoft/vcpkg.git
+      cd vcpkg
+      ./bootstrap-vcpkg.sh
+      ./vcpkg integrate install
+      vcpkg install raylib
+
+*The raylib port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.*
+
+#### Building raylib on multiple platforms
+
+[raylib Wiki](https://github.com/raysan5/raylib/wiki#development-platforms) contains detailed instructions on building and usage on multiple platforms.
+
+ - [Working on Windows](https://github.com/raysan5/raylib/wiki/Working-on-Windows)
+ - [Working on macOS](https://github.com/raysan5/raylib/wiki/Working-on-macOS)
+ - [Working on GNU Linux](https://github.com/raysan5/raylib/wiki/Working-on-GNU-Linux)
+ - [Working on FreeBSD](https://github.com/raysan5/raylib/wiki/Working-on-FreeBSD)
+ - [Working on Raspberry Pi](https://github.com/raysan5/raylib/wiki/Working-on-Raspberry-Pi)
+ - [Working for Android](https://github.com/raysan5/raylib/wiki/Working-for-Android)
+ - [Working for Web (HTML5)](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5))
+ - [Working for UWP (Universal Window Platform)](https://github.com/raysan5/raylib/wiki/Working-for-UWP)
+ - [Working anywhere with CMake](https://github.com/raysan5/raylib/wiki/Working-with-CMake)
+
+*Note that Wiki is open for edit, if you find some issue while building raylib for your target platform, feel free to edit the Wiki or open and issue related to it.*
 
-If you wish to build raylib yourself, [the raylib Wiki](https://github.com/raysan5/raylib/wiki) also contains detailed instructions on how to approach that.
+#### Using raylib with multiple IDEs
 
-raylib has been developed using two tools:
+raylib has been developed on Windows platform using [Notepad++](https://notepad-plus-plus.org/) and [MinGW GCC](http://mingw-w64.org/doku.php) compiler but it can be used with other IDEs on multiple platforms.
 
-   * Notepad++ (text editor) - [http://notepad-plus-plus.org](http://notepad-plus-plus.org/)
-   * MinGW (GCC compiler) - [http://www.mingw.org](http://www.mingw.org/)
+[Projects directory](https://github.com/raysan5/raylib/tree/master/projects) contains several ready-to-use **project templates** to build raylib and code examples with multiple IDEs.
 
-Those are the tools recommended to enjoy raylib development.
+*Note that there are lots of IDEs supported, some of the provided templates could require some review, please, if you find some issue with some template or you think they could be improved, feel free to send a PR or open a related issue.*
 
 contact
 -------
@@ -73,7 +113,7 @@ contact
    * Patreon: [https://www.patreon.com/raylib](https://www.patreon.com/raylib)
    * YouTube: [https://www.youtube.com/channel/raylib](https://www.youtube.com/channel/UC8WIBkhYb5sBNqXO1mZ7WSQ)
 
-If you are using raylib and you enjoy it, please, join our [Discord server](https://discord.gg/VkzNHUE).
+If you are using raylib and enjoying it, please, join our [Discord server](https://discord.gg/VkzNHUE) and let us know! :)
 
 license
 -------

+ 4 - 3
lib.mod/raylib/ROADMAP.md

@@ -3,18 +3,19 @@ roadmap
 
 Here it is a wish-list with features and ideas to improve the library. Note that features listed here are quite high-level and could be long term additions for the library. Current version of raylib is complete and functional but there is a lot of room for improvement.
 
-[raylib source code](https://github.com/raysan5/raylib/tree/master/src) has some *TODO* marks around code with pending things to review and improve. Check [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
+[raylib source code](https://github.com/raysan5/raylib/tree/master/src) has some *TODO* marks around code with pending things to review and improve. Check also [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
 
 **raylib 3.x**
  - [ ] Network module (UDP): `rnet` ([info](https://github.com/raysan5/raylib/issues/753))
  - [ ] Custom raylib resource packer: `rres` ([info](https://github.com/raysan5/rres))
- - [ ] Trace log messages redesign ([info](https://github.com/raysan5/raylib/issues/1065))
  - [ ] Basic CPU/GPU stats system (memory, draws, time...)
  - [ ] Continuous Deployment using GitHub Actions
  
  **raylib 3.0**
+ - [x] Custom memory allocators support
+ - [x] Global variables moved to global context
  - [x] Optimize data structures for pass-by-value
- - [x] Custom memory allocators support: `rmem`
+ - [x] Trace log messages redesign ([info](https://github.com/raysan5/raylib/issues/1065))
  - [x] Continuous Integration using GitHub Actions
  
 **raylib 2.5**

+ 1 - 1
lib.mod/raylib/appveyor.yml

@@ -39,7 +39,7 @@ before_build:
   - cd build
 
 build_script:
-  - cmake -G %GENERATOR% -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=%examples% -DBUILD_GAMES=%examples% -DINCLUDE_EVERYTHING=ON ..
+  - cmake -G %GENERATOR% -DCMAKE_BUILD_TYPE=Release -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=%examples% -DBUILD_GAMES=%examples% -DINCLUDE_EVERYTHING=ON ..
   - cmake --build . --target install
 
 after_build:

+ 4 - 3
lib.mod/raylib/examples/Makefile

@@ -25,8 +25,8 @@
 
 # Define required raylib variables
 PROJECT_NAME       ?= raylib_examples
-RAYLIB_VERSION     ?= 2.5.0
-RAYLIB_API_VERSION ?= 2
+RAYLIB_VERSION     ?= 3.0.0
+RAYLIB_API_VERSION ?= 3
 RAYLIB_PATH        ?= ..
 
 # Define default options
@@ -456,7 +456,8 @@ SHADERS = \
     shaders/shaders_eratosthenes \
     shaders/shaders_basic_lighting \
     shaders/shaders_fog \
-    shaders/shaders_simple_mask
+    shaders/shaders_simple_mask \
+    shaders/shaders_spotlight
     
 AUDIO = \
     audio/audio_module_playing \

+ 10 - 9
lib.mod/raylib/examples/Makefile.Android

@@ -26,8 +26,10 @@ PLATFORM               ?= PLATFORM_ANDROID
 RAYLIB_PATH            ?= ..\..
 
 # Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
+# Starting in 2019 using ARM64 is mandatory for published apps,
+# and minimum required target API is Android 9 (API level 28)
 ANDROID_ARCH           ?= ARM
-ANDROID_API_VERSION     = 21
+ANDROID_API_VERSION     = 28
 ifeq ($(ANDROID_ARCH),ARM)
     ANDROID_ARCH_NAME   = armeabi-v7a
 endif
@@ -36,11 +38,11 @@ ifeq ($(ANDROID_ARCH),ARM64)
 endif
 
 # Required path variables
-# NOTE: JAVA_HOME must be set to JDK
-JAVA_HOME              ?= C:/JavaJDK
+# NOTE: JAVA_HOME must be set to JDK (using OpenJDK 13)
+JAVA_HOME              ?= C:/open-jdk
 ANDROID_HOME            = C:/android-sdk
-ANDROID_TOOLCHAIN       = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
-ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/28.0.1
+ANDROID_TOOLCHAIN       = C:/android-ndk-r21/toolchains/llvm/prebuilt/windows-x86_64
+ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/29.0.3
 ANDROID_PLATFORM_TOOLS  = $(ANDROID_HOME)/platform-tools
 
 # Android project configuration variables
@@ -81,13 +83,12 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
 endif
 
 # Compiler and archiver
-# NOTE: GCC is being deprecated in Android NDK r16
 ifeq ($(ANDROID_ARCH),ARM)
-    CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
 endif
 ifeq ($(ANDROID_ARCH),ARM64)
-    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
 endif
 
@@ -274,7 +275,7 @@ zipalign_project_apk_package:
 # Install $(PROJECT_NAME).apk to default emulator/device
 # NOTE: Use -e (emulator) or -d (device) parameters if required
 install:
-	$(ANDROID_PLATFORM_TOOLS)/adb install --abi $(ANDROID_ARCH_NAME) -rds $(PROJECT_NAME).apk
+	$(ANDROID_PLATFORM_TOOLS)/adb install $(PROJECT_NAME).apk
     
 # Check supported ABI for the device (armeabi-v7a, arm64-v8a, x86, x86_64)
 check_device_abi:

+ 5 - 4
lib.mod/raylib/examples/core/core_basic_window.c

@@ -4,18 +4,19 @@
 *
 *   Welcome to raylib!
 *
-*   To test examples, just press F6 and execute raylib_compile_execute script
+*   To test examples in Notepad++, provided with default raylib installer package, 
+*   just press F6 and run [raylib_compile_execute] script, it will compile and execute.
 *   Note that compiled executable is placed in the same folder as .c file
 *
-*   You can find all basic examples on C:\raylib\raylib\examples folder or
-*   raylib official webpage: www.raylib.com
+*   You can find all basic examples on [C:\raylib\raylib\examples] directory and
+*   raylib official webpage: [www.raylib.com]
 *
 *   Enjoy using raylib. :)
 *
 *   This example has been created using raylib 1.0 (www.raylib.com)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
 *
-*   Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
+*   Copyright (c) 2013-2020 Ramon Santamaria (@raysan5)
 *
 ********************************************************************************************/
 

+ 23 - 1
lib.mod/raylib/examples/core/core_window_letterbox.c

@@ -1,6 +1,6 @@
 /*******************************************************************************************
 *
-*   raylib [core] example - window scale letterbox
+*   raylib [core] example - window scale letterbox (and virtual mouse)
 *
 *   This example has been created using raylib 2.5 (www.raylib.com)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@@ -16,6 +16,18 @@
 #define max(a, b) ((a)>(b)? (a) : (b))
 #define min(a, b) ((a)<(b)? (a) : (b))
 
+// Clamp Vector2 value with min and max and return a new vector2
+// NOTE: Required for virtual mouse, to clamp inside virtual game size
+Vector2 ClampValue(Vector2 value, Vector2 min, Vector2 max)
+{
+    Vector2 result = value;
+    result.x = (result.x > max.x)? max.x : result.x;
+    result.x = (result.x < min.x)? min.x : result.x;
+    result.y = (result.y > max.y)? max.y : result.y;
+    result.y = (result.y < min.y)? min.y : result.y;
+    return result;
+}
+
 int main(void)
 {
     const int windowWidth = 800;
@@ -52,6 +64,13 @@ int main(void)
             // Recalculate random colors for the bars
             for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
         }
+        
+        // Update virtual mouse (clamped mouse value behind game screen)
+        Vector2 mouse = GetMousePosition();
+        Vector2 virtualMouse = { 0 };
+        virtualMouse.x = (mouse.x - (GetScreenWidth() - (gameScreenWidth*scale))*0.5f)/scale;
+        virtualMouse.y = (mouse.y - (GetScreenHeight() - (gameScreenHeight*scale))*0.5f)/scale;
+        virtualMouse = ClampValue(virtualMouse, (Vector2){ 0, 0 }, (Vector2){ gameScreenWidth, gameScreenHeight }); 
         //----------------------------------------------------------------------------------
 
         // Draw
@@ -67,6 +86,9 @@ int main(void)
                 for (int i = 0; i < 10; i++) DrawRectangle(0, (gameScreenHeight/10)*i, gameScreenWidth, gameScreenHeight/10, colors[i]);
 
                 DrawText("If executed inside a window,\nyou can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE);
+                
+                DrawText(TextFormat("Default Mouse: [%i , %i]", (int)mouse.x, (int)mouse.y), 350, 25, 20, GREEN);
+                DrawText(TextFormat("Virtual Mouse: [%i , %i]", (int)virtualMouse.x, (int)virtualMouse.y), 350, 55, 20, YELLOW);
 
             EndTextureMode();
 

BIN
lib.mod/raylib/examples/core/core_window_letterbox.png


+ 0 - 1
lib.mod/raylib/examples/models/models_animation.c

@@ -37,7 +37,6 @@ int main(void)
     camera.fovy = 45.0f;                                // Camera field-of-view Y
     camera.type = CAMERA_PERSPECTIVE;                   // Camera mode type
 
-
     Model model = LoadModel("resources/guy/guy.iqm");               // Load the animated model mesh and basic data
     Texture2D texture = LoadTexture("resources/guy/guytex.png");    // Load model texture and set material
     SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture);  // Set model material map texture

+ 3 - 0
lib.mod/raylib/examples/models/models_material_pbr.c

@@ -2,6 +2,9 @@
 *
 *   raylib [models] example - PBR material
 *
+*   NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330
+*         is currently supported. OpenGL ES 2.0 platforms are not supported at the moment.
+*
 *   This example has been created using raylib 1.8 (www.raylib.com)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
 *

+ 0 - 133
lib.mod/raylib/examples/models/resources/shaders/glsl100/brdf.fs

@@ -1,133 +0,0 @@
-/*******************************************************************************************
-*
-*   BRDF LUT Generation - Bidirectional reflectance distribution function fragment shader
-*
-*   REF: https://github.com/HectorMF/BRDFGenerator
-*
-*   Copyright (c) 2017 Victor Fisac
-*
-**********************************************************************************************/
-
-#version 330
-
-
-// Input vertex attributes (from vertex shader)
-in vec2 fragTexCoord;
-
-// Constant values
-const float PI = 3.14159265359;
-const uint MAX_SAMPLES = 1024u;
-
-// Output fragment color
-out vec4 finalColor;
-
-vec2 Hammersley(uint i, uint N);
-float RadicalInverseVdC(uint bits);
-float GeometrySchlickGGX(float NdotV, float roughness);
-float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
-vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
-vec2 IntegrateBRDF(float NdotV, float roughness);
-
-float RadicalInverseVdC(uint bits)
-{
-    bits = (bits << 16u) | (bits >> 16u);
-    bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
-    bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
-    bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
-    bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
-    return float(bits) * 2.3283064365386963e-10; // / 0x100000000
-}
-
-// Compute Hammersley coordinates
-vec2 Hammersley(uint i, uint N)
-{
-	return vec2(float(i)/float(N), RadicalInverseVdC(i));
-}
-
-// Integrate number of importance samples for (roughness and NoV)
-vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
-{
-	float a = roughness*roughness;
-	float phi = 2.0 * PI * Xi.x;
-	float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
-	float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
-
-	// Transform from spherical coordinates to cartesian coordinates (halfway vector)
-	vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
-
-	// Transform from tangent space H vector to world space sample vector
-	vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
-	vec3 tangent = normalize(cross(up, N));
-	vec3 bitangent = cross(N, tangent);
-	vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
-
-	return normalize(sampleVec);
-}
-
-float GeometrySchlickGGX(float NdotV, float roughness)
-{
-    // For IBL k is calculated different
-    float k = (roughness*roughness)/2.0;
-
-    float nom = NdotV;
-    float denom = NdotV*(1.0 - k) + k;
-
-    return nom/denom;
-}
-
-// Compute the geometry term for the BRDF given roughness squared, NoV, NoL
-float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
-{
-    float NdotV = max(dot(N, V), 0.0);
-    float NdotL = max(dot(N, L), 0.0);
-    float ggx2 = GeometrySchlickGGX(NdotV, roughness);
-    float ggx1 = GeometrySchlickGGX(NdotL, roughness);
-
-    return ggx1*ggx2;
-}
-
-vec2 IntegrateBRDF(float NdotV, float roughness)
-{
-    float A = 0.0;
-    float B = 0.0;
-    vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
-    vec3 N = vec3(0.0, 0.0, 1.0);
-
-    for (uint i = 0u; i < MAX_SAMPLES; i++)
-    {
-        // Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
-        
-        vec2 Xi = Hammersley(i, MAX_SAMPLES);       // Compute a Hammersely coordinate
-        vec3 H = ImportanceSampleGGX(Xi, N, roughness); // Integrate number of importance samples for (roughness and NoV)
-        vec3 L = normalize(2.0*dot(V, H)*H - V);    // Compute reflection vector L
-        
-        float NdotL = max(L.z, 0.0);                // Compute normal dot light
-        float NdotH = max(H.z, 0.0);                // Compute normal dot half
-        float VdotH = max(dot(V, H), 0.0);          // Compute view dot half
-
-        if (NdotL > 0.0)
-        {
-            float G = GeometrySmith(N, V, L, roughness);    // Compute the geometry term for the BRDF given roughness squared, NoV, NoL
-            float GVis = (G*VdotH)/(NdotH*NdotV);   // Compute the visibility term given G, VoH, NoH, NoV, NoL
-            float Fc = pow(1.0 - VdotH, 5.0);       // Compute the fresnel term given VoH
-
-            A += (1.0 - Fc)*GVis;                   // Sum the result given fresnel, geometry, visibility
-            B += Fc*GVis;
-        }
-    }
-
-    // Calculate brdf average sample
-    A /= float(MAX_SAMPLES);
-    B /= float(MAX_SAMPLES);
-
-    return vec2(A, B);
-}
-
-void main()
-{
-    // Calculate brdf based on texture coordinates
-    vec2 brdf = IntegrateBRDF(fragTexCoord.x, fragTexCoord.y);
-
-    // Calculate final fragment color
-    finalColor = vec4(brdf.r, brdf.g, 0.0, 1.0);
-}

+ 0 - 25
lib.mod/raylib/examples/models/resources/shaders/glsl100/brdf.vs

@@ -1,25 +0,0 @@
-/*******************************************************************************************
-*
-*   rPBR [shader] - Bidirectional reflectance distribution function vertex shader
-*
-*   Copyright (c) 2017 Victor Fisac
-*
-**********************************************************************************************/
-
-#version 330
-
-// Input vertex attributes
-in vec3 vertexPosition;
-in vec2 vertexTexCoord;
-
-// Output vertex attributes (to fragment shader)
-out vec2 fragTexCoord;
-
-void main()
-{
-    // Calculate fragment position based on model transformations
-    fragTexCoord = vertexTexCoord;
-
-    // Calculate final vertex position
-    gl_Position = vec4(vertexPosition, 1.0);
-}

+ 0 - 58
lib.mod/raylib/examples/models/resources/shaders/glsl100/irradiance.fs

@@ -1,58 +0,0 @@
-/*******************************************************************************************
-*
-*   rPBR [shader] - Irradiance cubemap fragment shader
-*
-*   Copyright (c) 2017 Victor Fisac
-*
-**********************************************************************************************/
-
-#version 330
-
-// Input vertex attributes (from vertex shader)
-in vec3 fragPosition;
-
-// Input uniform values
-uniform samplerCube environmentMap;
-
-// Constant values
-const float PI = 3.14159265359f;
-
-// Output fragment color
-out vec4 finalColor;
-
-void main()
-{
-    // The sample direction equals the hemisphere's orientation
-    vec3 normal = normalize(fragPosition);
-
-    vec3 irradiance = vec3(0.0);  
-
-    vec3 up = vec3(0.0, 1.0, 0.0);
-    vec3 right = cross(up, normal);
-    up = cross(normal, right);
-
-    float sampleDelta = 0.025f;
-    float nrSamples = 0.0f; 
-
-    for (float phi = 0.0; phi < 2.0*PI; phi += sampleDelta)
-    {
-        for (float theta = 0.0; theta < 0.5*PI; theta += sampleDelta)
-        {
-            // Spherical to cartesian (in tangent space)
-            vec3 tangentSample = vec3(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta));
-            
-            // tangent space to world
-            vec3 sampleVec = tangentSample.x*right + tangentSample.y*up + tangentSample.z*normal; 
-
-            // Fetch color from environment cubemap
-            irradiance += texture(environmentMap, sampleVec).rgb*cos(theta)*sin(theta);
-            nrSamples++;
-        }
-    }
-
-    // Calculate irradiance average value from samples
-    irradiance = PI*irradiance*(1.0/float(nrSamples));
-
-    // Calculate final fragment color
-    finalColor = vec4(irradiance, 1.0);
-}

+ 0 - 298
lib.mod/raylib/examples/models/resources/shaders/glsl100/pbr.fs

@@ -1,298 +0,0 @@
-/*******************************************************************************************
-*
-*   rPBR [shader] - Physically based rendering fragment shader
-*
-*   Copyright (c) 2017 Victor Fisac
-*
-**********************************************************************************************/
-
-#version 330
-
-#define     MAX_REFLECTION_LOD      4.0
-#define     MAX_DEPTH_LAYER         20
-#define     MIN_DEPTH_LAYER         10
-
-#define     MAX_LIGHTS              4
-#define     LIGHT_DIRECTIONAL       0
-#define     LIGHT_POINT             1
-
-struct MaterialProperty {
-    vec3 color;
-    int useSampler;
-    sampler2D sampler;
-};
-
-struct Light {
-    int enabled;
-    int type;
-    vec3 position;
-    vec3 target;
-    vec4 color;
-};
-
-// Input vertex attributes (from vertex shader)
-in vec3 fragPosition;
-in vec2 fragTexCoord;
-in vec3 fragNormal;
-in vec3 fragTangent;
-in vec3 fragBinormal;
-
-// Input material values
-uniform MaterialProperty albedo;
-uniform MaterialProperty normals;
-uniform MaterialProperty metalness;
-uniform MaterialProperty roughness;
-uniform MaterialProperty occlusion;
-uniform MaterialProperty emission;
-uniform MaterialProperty height;
-
-// Input uniform values
-uniform samplerCube irradianceMap;
-uniform samplerCube prefilterMap;
-uniform sampler2D brdfLUT;
-
-// Input lighting values
-uniform Light lights[MAX_LIGHTS];
-
-// Other uniform values
-uniform int renderMode;
-uniform vec3 viewPos;
-vec2 texCoord;
-
-// Constant values
-const float PI = 3.14159265359;
-
-// Output fragment color
-out vec4 finalColor;
-
-vec3 ComputeMaterialProperty(MaterialProperty property);
-float DistributionGGX(vec3 N, vec3 H, float roughness);
-float GeometrySchlickGGX(float NdotV, float roughness);
-float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
-vec3 fresnelSchlick(float cosTheta, vec3 F0);
-vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness);
-vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir);
-
-vec3 ComputeMaterialProperty(MaterialProperty property)
-{
-    vec3 result = vec3(0.0, 0.0, 0.0);
-
-    if (property.useSampler == 1) result = texture(property.sampler, texCoord).rgb;
-    else result = property.color;
-
-    return result;
-}
-
-float DistributionGGX(vec3 N, vec3 H, float roughness)
-{
-    float a = roughness*roughness;
-    float a2 = a*a;
-    float NdotH = max(dot(N, H), 0.0);
-    float NdotH2 = NdotH*NdotH;
-
-    float nom = a2;
-    float denom = (NdotH2*(a2 - 1.0) + 1.0);
-    denom = PI*denom*denom;
-
-    return nom/denom;
-}
-
-float GeometrySchlickGGX(float NdotV, float roughness)
-{
-    float r = (roughness + 1.0);
-    float k = r*r/8.0;
-
-    float nom = NdotV;
-    float denom = NdotV*(1.0 - k) + k;
-
-    return nom/denom;
-}
-float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
-{
-    float NdotV = max(dot(N, V), 0.0);
-    float NdotL = max(dot(N, L), 0.0);
-    float ggx2 = GeometrySchlickGGX(NdotV, roughness);
-    float ggx1 = GeometrySchlickGGX(NdotL, roughness);
-
-    return ggx1*ggx2;
-}
-
-vec3 fresnelSchlick(float cosTheta, vec3 F0)
-{
-    return F0 + (1.0 - F0)*pow(1.0 - cosTheta, 5.0);
-}
-
-vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
-{
-    return F0 + (max(vec3(1.0 - roughness), F0) - F0)*pow(1.0 - cosTheta, 5.0);
-}
-
-vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir)
-{
-    // Calculate the number of depth layers and calculate the size of each layer
-    float numLayers = mix(MAX_DEPTH_LAYER, MIN_DEPTH_LAYER, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)));  
-    float layerDepth = 1.0/numLayers;
-
-    // Calculate depth of current layer
-    float currentLayerDepth = 0.0;
-
-    // Calculate the amount to shift the texture coordinates per layer (from vector P)
-    // Note: height amount is stored in height material attribute color R channel (sampler use is independent)
-    vec2 P = viewDir.xy*height.color.r; 
-    vec2 deltaTexCoords = P/numLayers;
-
-    // Store initial texture coordinates and depth values
-    vec2 currentTexCoords = texCoords;
-    float currentDepthMapValue = texture(height.sampler, currentTexCoords).r;
-
-    while (currentLayerDepth < currentDepthMapValue)
-    {
-        // Shift texture coordinates along direction of P
-        currentTexCoords -= deltaTexCoords;
-
-        // Get depth map value at current texture coordinates
-        currentDepthMapValue = texture(height.sampler, currentTexCoords).r;
-
-        // Get depth of next layer
-        currentLayerDepth += layerDepth;  
-    }
-
-    // Get texture coordinates before collision (reverse operations)
-    vec2 prevTexCoords = currentTexCoords + deltaTexCoords;
-
-    // Get depth after and before collision for linear interpolation
-    float afterDepth = currentDepthMapValue - currentLayerDepth;
-    float beforeDepth = texture(height.sampler, prevTexCoords).r - currentLayerDepth + layerDepth;
-
-    // Interpolation of texture coordinates
-    float weight = afterDepth/(afterDepth - beforeDepth);
-    vec2 finalTexCoords = prevTexCoords*weight + currentTexCoords*(1.0 - weight);
-
-    return finalTexCoords;
-}
-
-void main()
-{
-    // Calculate TBN and RM matrices
-    mat3 TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
-
-    // Calculate lighting required attributes
-    vec3 normal = normalize(fragNormal);
-    vec3 view = normalize(viewPos - fragPosition);
-    vec3 refl = reflect(-view, normal);
-
-    // Check if parallax mapping is enabled and calculate texture coordinates to use based on height map
-    // NOTE: remember that 'texCoord' variable must be assigned before calling any ComputeMaterialProperty() function
-    if (height.useSampler == 1) texCoord = ParallaxMapping(fragTexCoord, view);
-    else texCoord = fragTexCoord;   // Use default texture coordinates
-
-    // Fetch material values from texture sampler or color attributes
-    vec3 color = ComputeMaterialProperty(albedo);
-    vec3 metal = ComputeMaterialProperty(metalness);
-    vec3 rough = ComputeMaterialProperty(roughness);
-    vec3 emiss = ComputeMaterialProperty(emission);
-    vec3 ao = ComputeMaterialProperty(occlusion);
-
-    // Check if normal mapping is enabled
-    if (normals.useSampler == 1)
-    {
-        // Fetch normal map color and transform lighting values to tangent space
-        normal = ComputeMaterialProperty(normals);
-        normal = normalize(normal*2.0 - 1.0);
-        normal = normalize(normal*TBN);
-
-        // Convert tangent space normal to world space due to cubemap reflection calculations
-        refl = normalize(reflect(-view, normal));
-    }
-
-    // Calculate reflectance at normal incidence
-    vec3 F0 = vec3(0.04);
-    F0 = mix(F0, color, metal.r);
-
-    // Calculate lighting for all lights
-    vec3 Lo = vec3(0.0);
-    vec3 lightDot = vec3(0.0);
-
-    for (int i = 0; i < MAX_LIGHTS; i++)
-    {
-        if (lights[i].enabled == 1)
-        {
-            // Calculate per-light radiance
-            vec3 light = vec3(0.0);
-            vec3 radiance = lights[i].color.rgb;
-            if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position);
-            else if (lights[i].type == LIGHT_POINT)
-            {
-                light = normalize(lights[i].position - fragPosition);
-                float distance = length(lights[i].position - fragPosition);
-                float attenuation = 1.0/(distance*distance);
-                radiance *= attenuation;
-            }
-
-            // Cook-torrance BRDF
-            vec3 high = normalize(view + light);
-            float NDF = DistributionGGX(normal, high, rough.r);
-            float G = GeometrySmith(normal, view, light, rough.r);
-            vec3 F = fresnelSchlick(max(dot(high, view), 0.0), F0);
-            vec3 nominator = NDF*G*F;
-            float denominator = 4*max(dot(normal, view), 0.0)*max(dot(normal, light), 0.0) + 0.001;
-            vec3 brdf = nominator/denominator;
-
-            // Store to kS the fresnel value and calculate energy conservation
-            vec3 kS = F;
-            vec3 kD = vec3(1.0) - kS;
-
-            // Multiply kD by the inverse metalness such that only non-metals have diffuse lighting
-            kD *= 1.0 - metal.r;
-
-            // Scale light by dot product between normal and light direction
-            float NdotL = max(dot(normal, light), 0.0);
-
-            // Add to outgoing radiance Lo
-            // Note: BRDF is already multiplied by the Fresnel so it doesn't need to be multiplied again
-            Lo += (kD*color/PI + brdf)*radiance*NdotL*lights[i].color.a;
-            lightDot += radiance*NdotL + brdf*lights[i].color.a;
-        }
-    }
-
-    // Calculate ambient lighting using IBL
-    vec3 F = fresnelSchlickRoughness(max(dot(normal, view), 0.0), F0, rough.r);
-    vec3 kS = F;
-    vec3 kD = 1.0 - kS;
-    kD *= 1.0 - metal.r;
-
-    // Calculate indirect diffuse
-    vec3 irradiance = texture(irradianceMap, fragNormal).rgb;
-    vec3 diffuse = color*irradiance;
-
-    // Sample both the prefilter map and the BRDF lut and combine them together as per the Split-Sum approximation
-    vec3 prefilterColor = textureLod(prefilterMap, refl, rough.r*MAX_REFLECTION_LOD).rgb;
-    vec2 brdf = texture(brdfLUT, vec2(max(dot(normal, view), 0.0), rough.r)).rg;
-    vec3 reflection = prefilterColor*(F*brdf.x + brdf.y);
-
-    // Calculate final lighting
-    vec3 ambient = (kD*diffuse + reflection)*ao;
-
-    // Calculate fragment color based on render mode
-    vec3 fragmentColor = ambient + Lo + emiss;                              // Physically Based Rendering
-
-    if (renderMode == 1) fragmentColor = color;                             // Albedo
-    else if (renderMode == 2) fragmentColor = normal;                       // Normals
-    else if (renderMode == 3) fragmentColor = metal;                        // Metalness
-    else if (renderMode == 4) fragmentColor = rough;                        // Roughness
-    else if (renderMode == 5) fragmentColor = ao;                           // Ambient Occlusion
-    else if (renderMode == 6) fragmentColor = emiss;                        // Emission
-    else if (renderMode == 7) fragmentColor = lightDot;                     // Lighting
-    else if (renderMode == 8) fragmentColor = kS;                           // Fresnel
-    else if (renderMode == 9) fragmentColor = irradiance;                   // Irradiance
-    else if (renderMode == 10) fragmentColor = reflection;                  // Reflection
-
-    // Apply HDR tonemapping
-    fragmentColor = fragmentColor/(fragmentColor + vec3(1.0));
-
-    // Apply gamma correction
-    fragmentColor = pow(fragmentColor, vec3(1.0/2.2));
-
-    // Calculate final fragment color
-    finalColor = vec4(fragmentColor, 1.0);
-}

+ 0 - 49
lib.mod/raylib/examples/models/resources/shaders/glsl100/pbr.vs

@@ -1,49 +0,0 @@
-/*******************************************************************************************
-*
-*   rPBR [shader] - Physically based rendering vertex shader
-*
-*   Copyright (c) 2017 Victor Fisac
-*
-**********************************************************************************************/
-
-#version 330
-
-// Input vertex attributes
-in vec3 vertexPosition;
-in vec2 vertexTexCoord;
-in vec3 vertexNormal;
-in vec4 vertexTangent;
-
-// Input uniform values
-uniform mat4 mvp;
-uniform mat4 matModel;
-
-// Output vertex attributes (to fragment shader)
-out vec3 fragPosition;
-out vec2 fragTexCoord;
-out vec3 fragNormal;
-out vec3 fragTangent;
-out vec3 fragBinormal;
-
-void main()
-{
-    // Calculate binormal from vertex normal and tangent
-    vec3 vertexBinormal = cross(vertexNormal, vec3(vertexTangent));
-
-    // Calculate fragment normal based on normal transformations
-    mat3 normalMatrix = transpose(inverse(mat3(matModel)));
-
-    // Calculate fragment position based on model transformations
-    fragPosition = vec3(matModel*vec4(vertexPosition, 1.0f));
-
-    // Send vertex attributes to fragment shader
-    fragTexCoord = vertexTexCoord;
-    fragNormal = normalize(normalMatrix*vertexNormal);
-    fragTangent = normalize(normalMatrix*vec3(vertexTangent));
-    fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
-    fragBinormal = normalize(normalMatrix*vertexBinormal);
-    fragBinormal = cross(fragNormal, fragTangent);
-
-    // Calculate final vertex position
-    gl_Position = mvp*vec4(vertexPosition, 1.0);
-}

+ 0 - 120
lib.mod/raylib/examples/models/resources/shaders/glsl100/prefilter.fs

@@ -1,120 +0,0 @@
-/*******************************************************************************************
-*
-*   rPBR [shader] - Prefiltered environment for reflections fragment shader
-*
-*   Copyright (c) 2017 Victor Fisac
-*
-**********************************************************************************************/
-
-#version 330
-#define     MAX_SAMPLES             1024u
-#define     CUBEMAP_RESOLUTION      1024.0
-
-// Input vertex attributes (from vertex shader)
-in vec3 fragPosition;
-
-// Input uniform values
-uniform samplerCube environmentMap;
-uniform float roughness;
-
-// Constant values
-const float PI = 3.14159265359f;
-
-// Output fragment color
-out vec4 finalColor;
-
-float DistributionGGX(vec3 N, vec3 H, float roughness);
-float RadicalInverse_VdC(uint bits);
-vec2 Hammersley(uint i, uint N);
-vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
-
-float DistributionGGX(vec3 N, vec3 H, float roughness)
-{
-    float a = roughness*roughness;
-    float a2 = a*a;
-    float NdotH = max(dot(N, H), 0.0);
-    float NdotH2 = NdotH*NdotH;
-
-    float nom   = a2;
-    float denom = (NdotH2*(a2 - 1.0) + 1.0);
-    denom = PI*denom*denom;
-
-    return nom/denom;
-}
-
-float RadicalInverse_VdC(uint bits)
-{
-     bits = (bits << 16u) | (bits >> 16u);
-     bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
-     bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
-     bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
-     bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
-     return float(bits) * 2.3283064365386963e-10; // / 0x100000000
-}
-
-vec2 Hammersley(uint i, uint N)
-{
-	return vec2(float(i)/float(N), RadicalInverse_VdC(i));
-}
-
-vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
-{
-	float a = roughness*roughness;
-	float phi = 2.0 * PI * Xi.x;
-	float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
-	float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
-
-	// Transform from spherical coordinates to cartesian coordinates (halfway vector)
-	vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
-
-	// Transform from tangent space H vector to world space sample vector
-	vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
-	vec3 tangent = normalize(cross(up, N));
-	vec3 bitangent = cross(N, tangent);
-	vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
-
-	return normalize(sampleVec);
-}
-
-void main()
-{
-    // Make the simplyfying assumption that V equals R equals the normal 
-    vec3 N = normalize(fragPosition);
-    vec3 R = N;
-    vec3 V = R;
-
-    vec3 prefilteredColor = vec3(0.0);
-    float totalWeight = 0.0;
-
-    for (uint i = 0u; i < MAX_SAMPLES; i++)
-    {
-        // Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
-        vec2 Xi = Hammersley(i, MAX_SAMPLES);
-        vec3 H = ImportanceSampleGGX(Xi, N, roughness);
-        vec3 L  = normalize(2.0*dot(V, H)*H - V);
-
-        float NdotL = max(dot(N, L), 0.0);
-        if(NdotL > 0.0)
-        {
-            // Sample from the environment's mip level based on roughness/pdf
-            float D = DistributionGGX(N, H, roughness);
-            float NdotH = max(dot(N, H), 0.0);
-            float HdotV = max(dot(H, V), 0.0);
-            float pdf = D*NdotH/(4.0*HdotV) + 0.0001; 
-
-            float resolution = CUBEMAP_RESOLUTION;
-            float saTexel  = 4.0*PI/(6.0*resolution*resolution);
-            float saSample = 1.0/(float(MAX_SAMPLES)*pdf + 0.0001);
-            float mipLevel = ((roughness == 0.0) ? 0.0 : 0.5*log2(saSample/saTexel)); 
-
-            prefilteredColor += textureLod(environmentMap, L, mipLevel).rgb*NdotL;
-            totalWeight += NdotL;
-        }
-    }
-
-    // Calculate prefilter average color
-    prefilteredColor = prefilteredColor/totalWeight;
-
-    // Calculate final fragment color
-    finalColor = vec4(prefilteredColor, 1.0);
-}

BIN
lib.mod/raylib/examples/shaders/resources/raysan.png


+ 77 - 0
lib.mod/raylib/examples/shaders/resources/shaders/glsl100/spotlight.fs

@@ -0,0 +1,77 @@
+#version 100
+
+precision mediump float;
+
+#define MAX_SPOTS   3
+
+struct Spot {
+    vec2 pos;		// window coords of spot
+    float inner;	// inner fully transparent centre radius
+    float radius;	// alpha fades out to this radius
+};
+
+uniform Spot spots[MAX_SPOTS];  // Spotlight positions array
+uniform float screenWidth;      // Width of the screen
+
+void main()
+{
+	float alpha = 1.0;
+    
+	// Get the position of the current fragment (screen coordinates!)
+	vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
+	
+	// Find out which spotlight is nearest
+	float d = 65000.0;  // some high value
+	int fi = -1;        // found index
+
+    for (int i = 0; i < MAX_SPOTS; i++)
+    {
+		for (int j = 0; j < MAX_SPOTS; j++)
+		{
+			float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
+            
+			if (d > dj) 
+			{
+				d = dj;
+				fi = i;
+			}
+		}
+    }
+    
+    // d now equals distance to nearest spot...
+    // allowing for the different radii of all spotlights
+    if (fi == 0) 
+    {
+		if (d > spots[0].radius) alpha = 1.0;
+		else
+		{
+			if (d < spots[0].inner) alpha = 0.0;
+			else alpha = (d - spots[0].inner)/(spots[0].radius - spots[0].inner);
+		}
+	}
+    else if (fi == 1) 
+    {
+		if (d > spots[1].radius) alpha = 1.0;
+		else
+		{
+			if (d < spots[1].inner) alpha = 0.0;
+			else alpha = (d - spots[1].inner)/(spots[1].radius - spots[1].inner);
+		}
+	}
+    else if (fi == 2) 
+    {
+		if (d > spots[2].radius) alpha = 1.0;
+		else
+		{
+			if (d < spots[2].inner) alpha = 0.0;
+			else alpha = (d - spots[2].inner)/(spots[2].radius - spots[2].inner);
+		}
+	}
+	
+	// Right hand side of screen is dimly lit, 
+    // could make the threshold value user definable
+	if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
+
+	// could make the black out colour user definable...
+    gl_FragColor = vec4(0, 0, 0, alpha);
+}

+ 59 - 0
lib.mod/raylib/examples/shaders/resources/shaders/glsl120/base_lighting.vs

@@ -0,0 +1,59 @@
+#version 120
+
+// Input vertex attributes
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+attribute vec3 vertexNormal;
+attribute vec4 vertexColor;
+
+// Input uniform values
+uniform mat4 mvp;
+uniform mat4 matModel;
+
+// Output vertex attributes (to fragment shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// NOTE: Add here your custom variables
+
+// https://github.com/glslify/glsl-inverse
+mat3 inverse(mat3 m)
+{
+  float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
+  float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
+  float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
+
+  float b01 = a22*a11 - a12*a21;
+  float b11 = -a22*a10 + a12*a20;
+  float b21 = a21*a10 - a11*a20;
+
+  float det = a00*b01 + a01*b11 + a02*b21;
+
+  return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
+              b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
+              b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
+}
+
+// https://github.com/glslify/glsl-transpose
+mat3 transpose(mat3 m)
+{
+  return mat3(m[0][0], m[1][0], m[2][0],
+              m[0][1], m[1][1], m[2][1],
+              m[0][2], m[1][2], m[2][2]);
+}
+
+void main()
+{
+    // Send vertex attributes to fragment shader
+    fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
+    fragTexCoord = vertexTexCoord;
+    fragColor = vertexColor;
+    
+    mat3 normalMatrix = transpose(inverse(mat3(matModel)));
+    fragNormal = normalize(normalMatrix*vertexNormal);
+
+    // Calculate final vertex position
+    gl_Position = mvp*vec4(vertexPosition, 1.0);
+}

+ 92 - 0
lib.mod/raylib/examples/shaders/resources/shaders/glsl120/fog.fs

@@ -0,0 +1,92 @@
+#version 120
+
+// Input vertex attributes (from vertex shader)
+varying vec3 fragPosition;
+varying vec2 fragTexCoord;
+varying vec4 fragColor;
+varying vec3 fragNormal;
+
+// Input uniform values
+uniform sampler2D texture0;
+uniform vec4 colDiffuse;
+
+// NOTE: Add here your custom variables
+
+#define     MAX_LIGHTS              4
+#define     LIGHT_DIRECTIONAL       0
+#define     LIGHT_POINT             1
+
+struct MaterialProperty {
+    vec3 color;
+    int useSampler;
+    sampler2D sampler;
+};
+
+struct Light {
+    int enabled;
+    int type;
+    vec3 position;
+    vec3 target;
+    vec4 color;
+};
+
+// Input lighting values
+uniform Light lights[MAX_LIGHTS];
+uniform vec4 ambient;
+uniform vec3 viewPos;
+uniform float fogDensity;
+
+void main()
+{
+    // Texel color fetching from texture sampler
+    vec4 texelColor = texture2D(texture0, fragTexCoord);
+    vec3 lightDot = vec3(0.0);
+    vec3 normal = normalize(fragNormal);
+    vec3 viewD = normalize(viewPos - fragPosition);
+    vec3 specular = vec3(0.0);
+
+    // NOTE: Implement here your fragment shader code
+
+    for (int i = 0; i < MAX_LIGHTS; i++)
+    {
+        if (lights[i].enabled == 1)
+        {
+            vec3 light = vec3(0.0);
+            
+            if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position);
+            if (lights[i].type == LIGHT_POINT) light = normalize(lights[i].position - fragPosition);
+
+            float NdotL = max(dot(normal, light), 0.0);
+            lightDot += lights[i].color.rgb*NdotL;
+
+            float specCo = 0.0;
+            if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // Shine: 16.0
+            specular += specCo;
+        }
+    }
+
+    vec4 finalColor = (texelColor*((colDiffuse + vec4(specular,1))*vec4(lightDot, 1.0)));
+    finalColor += texelColor*(ambient/10.0);
+    
+    // Gamma correction
+    finalColor = pow(finalColor, vec4(1.0/2.2));
+    
+    // Fog calculation
+    float dist = length(viewPos - fragPosition);
+
+    // these could be parameters...
+    const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);
+    //const float fogDensity = 0.16;
+
+    // Exponential fog
+    float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity));
+
+    // Linear fog (less nice)
+    //const float fogStart = 2.0;
+    //const float fogEnd = 10.0;
+    //float fogFactor = (fogEnd - dist)/(fogEnd - fogStart);
+
+    fogFactor = clamp(fogFactor, 0.0, 1.0);
+
+    gl_FragColor = mix(fogColor, finalColor, fogFactor);
+}

+ 65 - 0
lib.mod/raylib/examples/shaders/resources/shaders/glsl330/spotlight.fs

@@ -0,0 +1,65 @@
+#version 330
+
+// Input vertex attributes (from vertex shader)
+in vec2 fragTexCoord;
+in vec4 fragColor;
+
+// Output fragment color
+out vec4 finalColor;
+
+// NOTE: Add here your custom variables
+
+#define MAX_SPOTS   3
+
+struct Spot {
+    vec2 pos;		// window coords of spot
+    float inner;	// inner fully transparent centre radius
+    float radius;	// alpha fades out to this radius
+};
+
+uniform Spot spots[MAX_SPOTS];      // Spotlight positions array
+uniform float screenWidth;          // Width of the screen
+
+void main()
+{
+	float alpha = 1.0;
+    
+	// Get the position of the current fragment (screen coordinates!)
+	vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
+	
+	// Find out which spotlight is nearest
+	float d = 65000;  // some high value
+	int fi = -1;      // found index
+
+    for (int i = 0; i < MAX_SPOTS; i++)
+    {
+		for (int j = 0; j < MAX_SPOTS; j++)
+		{
+			float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
+            
+			if (d > dj) 
+			{
+				d = dj;
+				fi = i;
+			}
+		}
+    }
+    
+    // d now equals distance to nearest spot...
+    // allowing for the different radii of all spotlights
+    if (fi != -1)
+    {
+		if (d > spots[fi].radius) alpha = 1.0;
+		else
+		{
+			if (d < spots[fi].inner) alpha = 0.0;
+			else alpha = (d - spots[fi].inner) / (spots[fi].radius - spots[fi].inner);
+		}
+	}
+	
+	// Right hand side of screen is dimly lit, 
+    // could make the threshold value user definable
+	if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
+
+    finalColor = vec4(0, 0, 0, alpha);
+}

+ 3 - 7
lib.mod/raylib/examples/shaders/shaders_raymarching.c

@@ -2,12 +2,8 @@
 *
 *   raylib [shaders] example - Raymarching shapes generation
 *
-*   NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
-*         OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
-*
-*   NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
-*         on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
-*         raylib comes with shaders ready for both versions, check raylib/shaders install folder
+*   NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330
+*         is currently supported. OpenGL ES 2.0 platforms are not supported at the moment.
 *
 *   This example has been created using raylib 2.0 (www.raylib.com)
 *   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@@ -20,7 +16,7 @@
 
 #if defined(PLATFORM_DESKTOP)
     #define GLSL_VERSION            330
-#else   // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+#else   // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB -> Not supported at this moment
     #define GLSL_VERSION            100
 #endif
 

+ 262 - 0
lib.mod/raylib/examples/shaders/shaders_spotlight.c

@@ -0,0 +1,262 @@
+/*******************************************************************************************
+*
+*   raylib [shaders] example - Simple shader mask
+*
+*   This example has been created using raylib 2.5 (www.raylib.com)
+*   raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
+*
+*   Example contributed by Chris Camacho (@codifies -  http://bedroomcoders.co.uk/) 
+*   and reviewed by Ramon Santamaria (@raysan5)
+*
+*   Copyright (c) 2019 Chris Camacho (@codifies) and Ramon Santamaria (@raysan5)
+*
+********************************************************************************************
+*
+*   The shader makes alpha holes in the forground to give the apearance of a top
+*   down look at a spotlight casting a pool of light...
+* 
+*   The right hand side of the screen there is just enough light to see whats
+*   going on without the spot light, great for a stealth type game where you
+*   have to avoid the spotlights.
+* 
+*   The left hand side of the screen is in pitch dark except for where the spotlights are.
+* 
+*   Although this example doesn't scale like the letterbox example, you could integrate
+*   the two techniques, but by scaling the actual colour of the render texture rather
+*   than using alpha as a mask.
+*
+********************************************************************************************/
+
+#include "raylib.h"
+#include "raymath.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(PLATFORM_DESKTOP)
+    #define GLSL_VERSION            330
+#else   // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
+    #define GLSL_VERSION            100
+#endif
+
+
+#define MAXSPOT           3	// NB must be the same as define in shader
+#define numStars        400
+
+
+// Spot data
+typedef struct {   
+    Vector2 pos;
+    Vector2 vel;
+    float inner;
+    float radius;
+    
+    // Shader locations
+    unsigned int posLoc;
+    unsigned int innerLoc;
+    unsigned int radiusLoc;
+} Spot;
+
+// Stars in the star field have a position and velocity
+typedef struct Star {
+    Vector2 pos;
+    Vector2 vel;
+} Star;
+
+void UpdateStar(Star *s);
+void ResetStar(Star *s);
+
+int main(void)
+{
+    // Initialization
+    //--------------------------------------------------------------------------------------
+    const int screenWidth = 800;
+    const int screenHeight = 450;
+
+    InitWindow(screenWidth, screenHeight, "raylib - shader spotlight");
+    HideCursor();
+
+    Texture texRay = LoadTexture("resources/raysan.png");
+    
+    Star stars[numStars] = { 0 };
+
+    for (int n = 0; n < numStars; n++) ResetStar(&stars[n]);
+
+    // Progress all the stars on, so they don't all start in the centre
+    for (int m = 0; m < screenWidth/2.0; m++) 
+    {
+        for (int n = 0; n < numStars; n++) UpdateStar(&stars[n]);
+    }
+
+    int frameCounter = 0;
+
+
+       
+    // Use default vert shader
+    Shader spotShader = LoadShader(0, FormatText("resources/shaders/glsl%i/spotlight.fs", GLSL_VERSION));
+    
+	// Get the locations of spots in the shader
+	Spot spots[MAXSPOT];
+/*
+    unsigned int posLoc;
+    unsigned int innerLoc;
+    unsigned int radiusLoc;
+*/    
+    for (int i = 0; i < MAXSPOT; i++) 
+    {
+		char posName[32] = "spots[x].pos\0";
+		char innerName[32] = "spots[x].inner\0";
+		char radiusName[32] = "spots[x].radius\0";
+
+		posName[6] = '0' + i;
+		innerName[6] = '0' + i;
+		radiusName[6] = '0' + i;
+		
+		spots[i].posLoc = GetShaderLocation(spotShader, posName);
+		spots[i].innerLoc = GetShaderLocation(spotShader, innerName);
+		spots[i].radiusLoc = GetShaderLocation(spotShader, radiusName);
+		
+	}
+	
+	// tell the shader how wide the screen is so we can have
+	// a pitch black half and a dimly lit half.
+	{
+		unsigned int wLoc = GetShaderLocation(spotShader, "screenWidth");
+		float sw = (float)GetScreenWidth();
+		SetShaderValue(spotShader, wLoc, &sw, UNIFORM_FLOAT);
+	}
+
+    // randomise the locations and velocities of the spotlights
+    // and initialise the shader locations
+    for (int i = 0; i < MAXSPOT; i++)
+    {
+		
+		spots[i].pos.x = GetRandomValue(64, screenWidth - 64);
+		spots[i].pos.y = GetRandomValue(64, screenHeight - 64);
+		spots[i].vel = (Vector2){ 0, 0 };
+        
+		while ((fabs(spots[i].vel.x) + fabs(spots[i].vel.y)) < 2)
+        {
+			spots[i].vel.x = GetRandomValue(-40, 40)/10.0;
+			spots[i].vel.y = GetRandomValue(-40, 40)/10.0;
+		}
+		
+		spots[i].inner = 28 * (i + 1);
+		spots[i].radius = 48 * (i + 1);
+		
+		SetShaderValue(spotShader, spots[i].posLoc, &spots[i].pos.x, UNIFORM_VEC2);
+		SetShaderValue(spotShader, spots[i].innerLoc, &spots[i].inner, UNIFORM_FLOAT);
+		SetShaderValue(spotShader, spots[i].radiusLoc, &spots[i].radius, UNIFORM_FLOAT);
+	}
+
+    SetTargetFPS(60);               // Set  to run at 60 frames-per-second
+    //--------------------------------------------------------------------------------------
+    
+    // Main game loop
+    while (!WindowShouldClose())    // Detect window close button or ESC key
+    {
+        // Update
+        //----------------------------------------------------------------------------------
+        frameCounter++;
+
+		// Move the stars, resetting them if the go offscreen
+        for (int n = 0; n < numStars; n++) UpdateStar(&stars[n]);
+
+		// Update the spots, send them to the shader
+		for (int i = 0; i < MAXSPOT; i++)
+        {
+			if ( i == 0 ) {
+				Vector2 mp = GetMousePosition();
+				spots[i].pos.x = mp.x;					
+				spots[i].pos.y = screenHeight - mp.y;
+			} else {
+				spots[i].pos.x += spots[i].vel.x;					
+				spots[i].pos.y += spots[i].vel.y;
+				
+				if (spots[i].pos.x < 64) spots[i].vel.x = -spots[i].vel.x;					
+				if (spots[i].pos.x > screenWidth - 64) spots[i].vel.x = -spots[i].vel.x;					
+				if (spots[i].pos.y < 64) spots[i].vel.y = -spots[i].vel.y;					
+				if (spots[i].pos.y > screenHeight - 64) spots[i].vel.y = -spots[i].vel.y;
+			}
+			
+			SetShaderValue(spotShader, spots[i].posLoc, &spots[i].pos.x, UNIFORM_VEC2);				
+		}
+			
+        // Draw
+        //----------------------------------------------------------------------------------
+        BeginDrawing();
+
+            ClearBackground(DARKBLUE);
+
+			// Draw stars and bobs
+            for (int n = 0; n < numStars; n++)
+            {
+				// Single pixel is just too small these days!
+                DrawRectangle(stars[n].pos.x, stars[n].pos.y, 2, 2, WHITE);
+            }
+
+            for (int i = 0; i < 16; i++)
+            {
+                DrawTexture(texRay,
+                    (screenWidth/2.0) + cos((frameCounter + i*8)/51.45f)*(screenWidth/2.2) - 32,
+                    (screenHeight/2.0) + sin((frameCounter + i*8)/17.87f)*(screenHeight/4.2),
+                    WHITE);
+            }
+
+			// Draw spot lights
+			BeginShaderMode(spotShader);
+				// instead of a blank rectangle you could render here
+				// a render texture of the full screen used to do screen
+				// scaling (slight adjustment to shader would be required
+				// to actually pay attention to the colour!)
+				DrawRectangle(0,0,screenWidth,screenHeight,WHITE);
+			EndShaderMode();
+
+            DrawFPS(10, 10);
+            
+            DrawText("Move the mouse!", 10, 30, 20, GREEN);
+            DrawText("Pitch Black", screenWidth * .2, screenHeight / 2, 20, GREEN);
+            DrawText("Dark", screenWidth * .66, screenHeight / 2, 20, GREEN);
+            
+
+        EndDrawing();
+        //----------------------------------------------------------------------------------
+    }
+
+    // De-Initialization
+    //--------------------------------------------------------------------------------------
+    UnloadTexture(texRay);
+
+    CloseWindow();        // Close window and OpenGL context
+    //--------------------------------------------------------------------------------------
+
+    return 0;
+}
+
+
+void ResetStar(Star *s)
+{
+    s->pos = (Vector2){ GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
+    
+    do
+    {
+        s->vel.x = (float)GetRandomValue(-1000, 1000)/100.0f;
+        s->vel.y = (float)GetRandomValue(-1000, 1000)/100.0f;
+        
+    } while (!(fabs(s->vel.x) + fabs(s->vel.y) > 1));
+    
+    s->pos = Vector2Add(s->pos, Vector2MultiplyV(s->vel, (Vector2){ 8, 8 }));
+}
+
+void UpdateStar(Star *s)
+{
+    s->pos = Vector2Add(s->pos, s->vel);
+    
+    if (s->pos.x < 0 || s->pos.x > GetScreenWidth() ||
+        s->pos.y < 0 || s->pos.y > GetScreenHeight())
+    {
+        ResetStar(s);
+    }
+}
+
+

BIN
lib.mod/raylib/examples/shaders/shaders_spotlight.png


+ 5 - 0
lib.mod/raylib/examples/textures/textures_image_drawing.c

@@ -35,6 +35,11 @@ int main(void)
     ImageDraw(&parrots, cat, (Rectangle){ 0, 0, cat.width, cat.height }, (Rectangle){ 30, 40, cat.width*1.5f, cat.height*1.5f }, WHITE);
     ImageCrop(&parrots, (Rectangle){ 0, 50, parrots.width, parrots.height - 100 }); // Crop resulting image
 
+    // Draw on the image with a few image draw methods
+    ImageDrawPixel(&parrots, 10, 10, RAYWHITE);
+    ImageDrawCircle(&parrots, 10, 10, 5, RAYWHITE);
+    ImageDrawRectangle(&parrots, 5, 20, 10, 10, RAYWHITE);
+
     UnloadImage(cat);       // Unload image from RAM
 
     // Load custom font for frawing on image

BIN
lib.mod/raylib/examples/textures/textures_image_drawing.png


+ 82 - 1
lib.mod/raylib/projects/Notepad++/c_raylib.xml

@@ -982,9 +982,90 @@
         </KeyWord>
         <KeyWord name="ImageDrawRectangle" func="yes">
             <Overload retVal="void" descr="Draw rectangle within an image">
+                <Param name="Image *dst" />
+                <Param name="int posX" />
+                <Param name="int posY" />
+                <Param name="int width" />
+                <Param name="int height" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawRectangleV" func="yes">
+            <Overload retVal="void" descr="Draw rectangle within an image (Vector version)">
                 <Param name="Image *dst" />
                 <Param name="Vector2 position" />
+                <Param name="Vector2 size" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawRectangleRec" func="yes">
+            <Overload retVal="void" descr="Draw rectangle within an image">
+                <Param name="Image *dst" />
+                <Param name="Rectangle rec" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawRectangleLines" func="yes">
+            <Overload retVal="void" descr="Draw rectangle lines within an image">
+                <Param name="Image *dst" />
                 <Param name="Rectangle rec" />
+                <Param name="int thick" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageClearBackground" func="yes">
+            <Overload retVal="void" descr="Clear image background with given color">
+                <Param name="Image *dst" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawPixel" func="yes">
+            <Overload retVal="void" descr="Clear image background with given color">
+                <Param name="Image *dst" />
+		<Param name="int posX" />
+		<Param name="int posY" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawPixelV" func="yes">
+            <Overload retVal="void" descr="Clear image background with given color (Vector version)">
+                <Param name="Image *dst" />
+		<Param name="Vector2 position" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawCircle" func="yes">
+            <Overload retVal="void" descr="Draw circle within an image">
+                <Param name="Image *dst" />
+		<Param name="int centerX" />
+		<Param name="int centerY" />
+		<Param name="int radius" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawCircleV" func="yes">
+            <Overload retVal="void" descr="Draw circle within an image (Vector version)">
+                <Param name="Image *dst" />
+		<Param name="Vector2 center" />
+		<Param name="int radius" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawLine" func="yes">
+            <Overload retVal="void" descr="Draw line within an image">
+                <Param name="Image *dst" />
+		<Param name="int startPosX" />
+		<Param name="int startPosY" />
+		<Param name="int endPosX" />
+		<Param name="int endPosY" />
+                <Param name="Color color" />
+            </Overload>
+        </KeyWord>
+        <KeyWord name="ImageDrawLineV" func="yes">
+            <Overload retVal="void" descr="Draw line within an image (Vector2 version)">
+                <Param name="Image *dst" />
+		<Param name="Vector2 start" />
+		<Param name="Vector2 end" />
                 <Param name="Color color" />
             </Overload>
         </KeyWord>
@@ -2114,4 +2195,4 @@
             </Overload>
         </KeyWord>
     </AutoComplete>
-</NotepadPlus>
+</NotepadPlus>

+ 11 - 8
lib.mod/raylib/projects/scripts/build-windows.bat

@@ -10,6 +10,9 @@ set SOURCES=core_basic_window.c
 REM Set your raylib\src location here (relative path!)
 set RAYLIB_SRC=..\..\src
 
+REM Set the target platform for the compiler (Ex: x86 or x64)
+set TARGET_PLATFORM=x86
+
 REM About this build script: it does many things, but in essence, it's
 REM very simple. It has 3 compiler invocations: building raylib (which
 REM is not done always, see logic by searching "Build raylib"), building
@@ -63,7 +66,7 @@ IF NOT "%1" == "" (
 
 
 :HELP
-echo Usage: windows-build.bat [-hdurcqqv]
+echo Usage: build-windows.bat [-hdurcqqv]
 echo  -h  Show this information
 echo  -d  Faster builds that have debug symbols, and enable warnings
 echo  -u  Run upx* on the executable after compilation (before -r)
@@ -81,10 +84,10 @@ echo   easier, and it's a very small bit in the build scripts. The option
 echo   requires that you have upx installed and on your path, of course.
 echo.
 echo Examples:
-echo  Build a release build:                    windows-build.bat
-echo  Build a release build, full recompile:    windows-build.bat -c
-echo  Build a debug build and run:              windows-build.bat -d -r
-echo  Build in debug, run, don't print at all:  windows-build.bat -drqq
+echo  Build a release build:                    build-windows.bat
+echo  Build a release build, full recompile:    build-windows.bat -c
+echo  Build a debug build and run:              build-windows.bat -d -r
+echo  Build in debug, run, don't print at all:  build-windows.bat -drqq
 exit /B
 
 
@@ -104,9 +107,9 @@ IF EXIST "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxil
   exit /B
 )
 IF DEFINED VERBOSE (
-  call !VC_INIT! x86
+  call !VC_INIT! !TARGET_PLATFORM!
 ) ELSE (
-  call !VC_INIT! x86 > NUL 2>&1
+  call !VC_INIT! !TARGET_PLATFORM! > NUL 2>&1
 )
 
 
@@ -128,7 +131,7 @@ IF DEFINED BUILD_DEBUG (
   set OUTPUT_FLAG=/Fe: "!GAME_NAME!"
   set COMPILATION_FLAGS=/Od /Zi
   set WARNING_FLAGS=/Wall
-  set SUBSYSTEM_FLAGS=
+  set SUBSYSTEM_FLAGS=/DEBUG
   set LINK_FLAGS=/link kernel32.lib user32.lib shell32.lib winmm.lib gdi32.lib opengl32.lib
   set OUTPUT_DIR=builds-debug\windows-msvc
 )

+ 7 - 2
lib.mod/raylib/src/CMakeLists.txt

@@ -3,8 +3,8 @@ project(raylib C)
 include(GNUInstallDirs)
 list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
 
-set(PROJECT_VERSION 2.6.0)
-set(API_VERSION 261)
+set(PROJECT_VERSION 3.0.0)
+set(API_VERSION 301)
 
 include("CMakeOptions.txt")
 include(BuildType)
@@ -263,6 +263,11 @@ file(COPY "raymath.h" DESTINATION ".")
 file(COPY "raudio.h" DESTINATION ".")
 
 # Print the flags for the user
+if (DEFINED CMAKE_BUILD_TYPE)
+  message(STATUS "Generated build type: ${CMAKE_BUILD_TYPE}")
+else()
+  message(STATUS "Generated config types: ${CMAKE_CONFIGURATION_TYPES}")
+endif()
 message(STATUS "Compiling with the flags:")
 message(STATUS "  PLATFORM=" ${PLATFORM_CPP})
 message(STATUS "  GRAPHICS=" ${GRAPHICS})

+ 16 - 17
lib.mod/raylib/src/Makefile

@@ -157,24 +157,19 @@ endif
 
 ifeq ($(PLATFORM),PLATFORM_ANDROID)
     # Android architecture: ARM64
-    # Starting at 2019 using ARM64 is mandatory for published apps
+    # Starting at 2019 using ARM64 is mandatory for published apps,
+    # and minimum required target API is Android 9 (API level 28)
     ANDROID_ARCH ?= ARM
-    ANDROID_API_VERSION = 26
+    ANDROID_API_VERSION = 28
 
     # Android required path variables
-    # NOTE: Android NDK is just required to generate the standalone toolchain,
-    # in case is not already provided
+    # NOTE: Starting with Android NDK r21, no more toolchain generation is required, NDK is the toolchain on itself
     ifeq ($(OS),Windows_NT)
-        ANDROID_NDK = C:/android-ndk
+        ANDROID_NDK = C:/android-ndk-r21
+        ANDROID_TOOLCHAIN = $(ANDROID_NDK)/toolchains/llvm/prebuilt/windows-x86_64
     else
         ANDROID_NDK = /usr/lib/android/ndk
-    endif
-
-    # Android standalone toolchain path
-    ifeq ($(OS),Windows_NT)
-        ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
-    else
-        ANDROID_TOOLCHAIN = /usr/lib/android/toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
+        ANDROID_TOOLCHAIN = $(ANDROID_NDK)/toolchains/llvm/prebuilt/linux
     endif
 
     ifeq ($(ANDROID_ARCH),ARM)
@@ -219,7 +214,7 @@ ifeq ($(PLATFORM),PLATFORM_ANDROID)
 endif
 
 # Define default C compiler and archiver to pack library
-CC ?= gcc
+CC = gcc
 AR = ar
 
 ifeq ($(PLATFORM),PLATFORM_DESKTOP)
@@ -248,11 +243,11 @@ endif
 ifeq ($(PLATFORM),PLATFORM_ANDROID)
     # Android toolchain (must be provided for desired architecture and compiler)
     ifeq ($(ANDROID_ARCH),ARM)
-        CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
+        CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
         AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
     endif
     ifeq ($(ANDROID_ARCH),ARM64)
-        CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
+        CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
         AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
     endif
     ifeq ($(ANDROID_ARCH),x86)
@@ -298,9 +293,13 @@ endif
 ifeq ($(RAYLIB_BUILD_MODE),RELEASE)
     ifeq ($(PLATFORM),PLATFORM_WEB)
         CFLAGS += -Os
-    else
+    endif
+    ifeq ($(PLATFORM),PLATFORM_DESKTOP)
         CFLAGS += -s -O1
     endif
+    ifeq ($(PLATFORM),PLATFORM_ANDROID)
+        CFLAGS += -O2
+    endif
 endif
 
 # Additional flags for compiler (if desired)
@@ -485,7 +484,7 @@ else
         ifeq ($(PLATFORM),PLATFORM_DESKTOP)
             ifeq ($(PLATFORM_OS),WINDOWS)
                 # TODO: Compile resource file raylib.dll.rc for linkage on raylib.dll generation
-				$(CC) -shared -o $(RAYLIB_RELEASE_PATH)/raylib.dll $(OBJS) -L$(RAYLIB_RELEASE_PATH) -static-libgcc -lopengl32 -lgdi32 -lwinmm -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/libraylibdll.a
+				$(CC) -shared -o $(RAYLIB_RELEASE_PATH)/raylib.dll $(OBJS) $(RAYLIB_RELEASE_PATH)/raylib.dll.rc.data -L$(RAYLIB_RELEASE_PATH) -static-libgcc -lopengl32 -lgdi32 -lwinmm -Wl,--out-implib,$(RAYLIB_RELEASE_PATH)/libraylib.dll.a
 				@echo "raylib dynamic library (raylib.dll) and import library (libraylibdll.a) generated!"
             endif
             ifeq ($(PLATFORM_OS),LINUX)

+ 24 - 26
lib.mod/raylib/src/camera.h

@@ -197,22 +197,23 @@ typedef enum {
     MOVE_DOWN
 } CameraMove;
 
+// Camera global state context data
 typedef struct {
-    int mode;                     // Current camera mode
-    float targetDistance;         // Camera distance from position to target
-    float playerEyesPosition;     // Default player eyes position from ground (in meters)
-    Vector2 angle;                // Camera angle in plane XZ
+    int mode;                       // Current camera mode
+    float targetDistance;           // Camera distance from position to target
+    float playerEyesPosition;       // Default player eyes position from ground (in meters)
+    Vector2 angle;                  // Camera angle in plane XZ
 
     int moveControl[6];
-    int smoothZoomControl;        // raylib: KEY_LEFT_CONTROL
-    int altControl;               // raylib: KEY_LEFT_ALT
-    int panControl;               // raylib: MOUSE_MIDDLE_BUTTON
+    int smoothZoomControl;          // raylib: KEY_LEFT_CONTROL
+    int altControl;                 // raylib: KEY_LEFT_ALT
+    int panControl;                 // raylib: MOUSE_MIDDLE_BUTTON
 } CameraData;
 
 //----------------------------------------------------------------------------------
 // Global Variables Definition
 //----------------------------------------------------------------------------------
-static CameraData CAMERA = {
+static CameraData CAMERA = {        // Global CAMERA state context
     .mode = 0,
     .targetDistance = 0,
     .playerEyesPosition = 1.85f,
@@ -228,7 +229,6 @@ static CameraData CAMERA = {
 //----------------------------------------------------------------------------------
 #if defined(CAMERA_STANDALONE)
 // NOTE: Camera controls depend on some raylib input functions
-// TODO: Set your own input functions (used in UpdateCamera())
 static void EnableCursor() {}       // Unlock cursor
 static void DisableCursor() {}      // Lock cursor
 
@@ -273,13 +273,13 @@ void SetCameraMode(Camera camera, int mode)
 //       System: EnableCursor(), DisableCursor()
 //       Mouse: IsMouseButtonDown(), GetMousePosition(), GetMouseWheelMove()
 //       Keys:  IsKeyDown()
-// TODO: Port to quaternion-based camera
+// TODO: Port to quaternion-based camera (?)
 void UpdateCamera(Camera *camera)
 {
     static int swingCounter = 0;    // Used for 1st person swinging movement
     static Vector2 previousMousePosition = { 0.0f, 0.0f };
 
-    // TODO: Compute CAMERA.targetDistance and CAMERA.angle here
+    // TODO: Compute CAMERA.targetDistance and CAMERA.angle here (?)
 
     // Mouse movement detection
     Vector2 mousePositionDelta = { 0.0f, 0.0f };
@@ -290,7 +290,6 @@ void UpdateCamera(Camera *camera)
     bool panKey = IsMouseButtonDown(CAMERA.panControl);
     bool altKey = IsKeyDown(CAMERA.altControl);
     bool szoomKey = IsKeyDown(CAMERA.smoothZoomControl);
-
     bool direction[6] = { IsKeyDown(CAMERA.moveControl[MOVE_FRONT]),
                           IsKeyDown(CAMERA.moveControl[MOVE_BACK]),
                           IsKeyDown(CAMERA.moveControl[MOVE_RIGHT]),
@@ -298,7 +297,7 @@ void UpdateCamera(Camera *camera)
                           IsKeyDown(CAMERA.moveControl[MOVE_UP]),
                           IsKeyDown(CAMERA.moveControl[MOVE_DOWN]) };
 
-    // TODO: Consider touch inputs for camera
+    // TODO: Touch input detection (probably gestures system required)
 
     if (CAMERA.mode != CAMERA_CUSTOM)
     {
@@ -309,19 +308,20 @@ void UpdateCamera(Camera *camera)
     }
 
     // Support for multiple automatic camera modes
+    // NOTE: In case of CAMERA_CUSTOM nothing happens here, user must update it manually
     switch (CAMERA.mode)
     {
-        case CAMERA_FREE:
+        case CAMERA_FREE:           // Camera free controls, using standard 3d-content-creation scheme
         {
             // Camera zoom
             if ((CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
             {
                 CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
-
                 if (CAMERA.targetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
             }
+            
             // Camera looking down
-            // TODO: Review, weird comparisson of CAMERA.targetDistance == 120.0f?
+            // TODO: Review, weird comparison of CAMERA.targetDistance == 120.0f?
             else if ((camera->position.y > camera->target.y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
             {
                 camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
@@ -397,8 +397,9 @@ void UpdateCamera(Camera *camera)
             camera->position.x = -sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x;
             camera->position.y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance + camera->target.y;
             camera->position.z = -cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
+
         } break;
-        case CAMERA_ORBITAL:
+        case CAMERA_ORBITAL:        // Camera just orbits around target, only zoom allowed
         {
             CAMERA.angle.x += CAMERA_ORBITAL_SPEED;      // Camera orbit angle
             CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);   // Camera zoom
@@ -412,7 +413,7 @@ void UpdateCamera(Camera *camera)
             camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
 
         } break;
-        case CAMERA_FIRST_PERSON:
+        case CAMERA_FIRST_PERSON:   // Camera moves as in a first-person game, controls are configurable
         {
             camera->position.x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
                                    sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
@@ -428,10 +429,6 @@ void UpdateCamera(Camera *camera)
                                    sinf(CAMERA.angle.x)*direction[MOVE_LEFT] -
                                    sinf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
 
-            bool isMoving = false;  // Required for swinging
-
-            for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; }
-
             // Camera orientation calculation
             CAMERA.angle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
             CAMERA.angle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
@@ -448,8 +445,9 @@ void UpdateCamera(Camera *camera)
             camera->target.x = camera->position.x - transform.m12;
             camera->target.y = camera->position.y - transform.m13;
             camera->target.z = camera->position.z - transform.m14;
-
-            if (isMoving) swingCounter++;
+            
+            // If movement detected (some key pressed), increase swinging
+            for (int i = 0; i < 6; i++) if (direction[i]) { swingCounter++; break; }
 
             // Camera position update
             // NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
@@ -458,9 +456,8 @@ void UpdateCamera(Camera *camera)
             camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
             camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
 
-
         } break;
-        case CAMERA_THIRD_PERSON:
+        case CAMERA_THIRD_PERSON:   // Camera moves as in a third-person game, following target at a distance, controls are configurable
         {
             camera->position.x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
                                    sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
@@ -497,6 +494,7 @@ void UpdateCamera(Camera *camera)
             camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
 
         } break;
+        case CAMERA_CUSTOM: break;
         default: break;
     }
 }

+ 7 - 7
lib.mod/raylib/src/config.h

@@ -53,7 +53,7 @@
 // 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
 // Allow scale all the drawn content to match the high-DPI equivalent size (only PLATFORM_DESKTOP)
@@ -84,15 +84,15 @@
 //------------------------------------------------------------------------------------
 // Selecte desired fileformats to be supported for image data loading
 #define SUPPORT_FILEFORMAT_PNG      1
-//#define SUPPORT_FILEFORMAT_BMP    1
-//#define SUPPORT_FILEFORMAT_TGA    1
+#define SUPPORT_FILEFORMAT_BMP      1
+#define SUPPORT_FILEFORMAT_TGA      1
 #define SUPPORT_FILEFORMAT_JPG    1
 #define SUPPORT_FILEFORMAT_GIF      1
 //#define SUPPORT_FILEFORMAT_PSD    1
-#define SUPPORT_FILEFORMAT_DDS    1
-#define SUPPORT_FILEFORMAT_HDR    1
-//#define SUPPORT_FILEFORMAT_KTX    1
-//#define SUPPORT_FILEFORMAT_ASTC   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
 

File diff suppressed because it is too large
+ 149 - 194
lib.mod/raylib/src/core.c


+ 98 - 70
lib.mod/raylib/src/models.c

@@ -50,20 +50,41 @@
 #include <string.h>         // Required for: strncmp() [Used in LoadModelAnimations()], strlen() [Used in LoadTextureFromCgltfImage()]
 #include <math.h>           // Required for: sinf(), cosf(), sqrtf(), fabsf()
 
+#if defined(_WIN32)
+    #include <direct.h>     // Required for: _chdir() [Used in LoadOBJ()]
+    #define CHDIR _chdir
+#else
+    #include <unistd.h>     // Required for: chdir() (POSIX) [Used in LoadOBJ()]
+    #define CHDIR chdir
+#endif
+
 #include "rlgl.h"           // raylib OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
 
 #if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL)
+    #define TINYOBJ_MALLOC RL_MALLOC
+    #define TINYOBJ_CALLOC RL_CALLOC
+    #define TINYOBJ_REALLOC RL_REALLOC
+    #define TINYOBJ_FREE RL_FREE
+
     #define TINYOBJ_LOADER_C_IMPLEMENTATION
     #include "external/tinyobj_loader_c.h"      // OBJ/MTL file formats loading
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_GLTF)
+    #define CGLTF_MALLOC RL_MALLOC
+    #define CGLTF_FREE RL_FREE
+
     #define CGLTF_IMPLEMENTATION
     #include "external/cgltf.h"         // glTF file format loading
     #include "external/stb_image.h"     // glTF texture images loading
 #endif
 
 #if defined(SUPPORT_MESH_GENERATION)
+    #define PAR_MALLOC(T, N) ((T*)RL_MALLOC(N*sizeof(T)))
+    #define PAR_CALLOC(T, N) ((T*)RL_CALLOC(N*sizeof(T), 1))
+    #define PAR_REALLOC(T, BUF, N) ((T*)RL_REALLOC(BUF, sizeof(T)*(N)))
+    #define PAR_FREE RL_FREE
+
     #define PAR_SHAPES_IMPLEMENTATION
     #include "external/par_shapes.h"    // Shapes 3d parametric generation
 #endif
@@ -667,10 +688,10 @@ Model LoadModel(const char *fileName)
         model.meshCount = 1;
         model.meshes = (Mesh *)RL_CALLOC(model.meshCount, sizeof(Mesh));
 #if defined(SUPPORT_MESH_GENERATION)
-        TRACELOG(LOG_WARNING, "[%s] No meshes can be loaded, default to cube mesh", fileName);
+        TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load mesh data, default to cube mesh", fileName);
         model.meshes[0] = GenMeshCube(1.0f, 1.0f, 1.0f);
 #else
-        TRACELOG(LOG_WARNING, "[%s] No meshes can be loaded, and can't create a default mesh. The raylib mesh generation is not supported (SUPPORT_MESH_GENERATION).", fileName);
+        TRACELOG(LOG_WARNING, "MESH: [%s] Failed to load mesh data", fileName);
 #endif
     }
     else
@@ -681,7 +702,7 @@ Model LoadModel(const char *fileName)
 
     if (model.materialCount == 0)
     {
-        TRACELOG(LOG_WARNING, "[%s] No materials can be loaded, default to white material", fileName);
+        TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to load material data, default to white material", fileName);
 
         model.materialCount = 1;
         model.materials = (Material *)RL_CALLOC(model.materialCount, sizeof(Material));
@@ -735,7 +756,7 @@ void UnloadModel(Model model)
     RL_FREE(model.bones);
     RL_FREE(model.bindPose);
 
-    TRACELOG(LOG_INFO, "Unloaded model data from RAM and VRAM");
+    TRACELOG(LOG_INFO, "MODEL: Unloaded model from RAM and VRAM");
 }
 
 // Load meshes from model file
@@ -809,8 +830,8 @@ void ExportMesh(Mesh mesh, const char *fileName)
     }
     else if (IsFileExtension(fileName, ".raw")) { }   // TODO: Support additional file formats to export mesh vertex data
 
-    if (success) TRACELOG(LOG_INFO, "Mesh exported successfully: %s", fileName);
-    else TRACELOG(LOG_WARNING, "Mesh could not be exported.");
+    if (success) TRACELOG(LOG_INFO, "FILEIO: [%s] Mesh exported successfully", fileName);
+    else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export mesh data", fileName);
 }
 
 // Load materials from model file
@@ -828,7 +849,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount)
 
         int result = tinyobj_parse_mtl_file(&mats, &count, fileName);
         if (result != TINYOBJ_SUCCESS) {
-            TRACELOG(LOG_WARNING, "[%s] Could not parse Materials file", fileName);
+            TRACELOG(LOG_WARNING, "MATERIAL: [%s] Failed to parse materials file", fileName);
         }
 
         // TODO: Process materials to return
@@ -836,7 +857,7 @@ Material *LoadMaterials(const char *fileName, int *materialCount)
         tinyobj_materials_free(mats, count);
     }
 #else
-    TRACELOG(LOG_WARNING, "[%s] Materials file not supported", fileName);
+    TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to load material file", fileName);
 #endif
 
     // Set materials shader to default (DIFFUSE, SPECULAR, NORMAL)
@@ -888,8 +909,8 @@ void SetMaterialTexture(Material *material, int mapType, Texture2D texture)
 // Set the material for a mesh
 void SetModelMeshMaterial(Model *model, int meshId, int materialId)
 {
-    if (meshId >= model->meshCount) TRACELOG(LOG_WARNING, "Mesh id greater than mesh count");
-    else if (materialId >= model->materialCount) TRACELOG(LOG_WARNING,"Material id greater than material count");
+    if (meshId >= model->meshCount) TRACELOG(LOG_WARNING, "MESH: Id greater than mesh count");
+    else if (materialId >= model->materialCount) TRACELOG(LOG_WARNING, "MATERIAL: Id greater than material count");
     else  model->meshMaterial[meshId] = materialId;
 }
 
@@ -937,7 +958,8 @@ ModelAnimation *LoadModelAnimations(const char *filename, int *animCount)
 
     if (!iqmFile)
     {
-        TRACELOG(LOG_ERROR, "[%s] Unable to open file", filename);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", filename);
+        return NULL;
     }
 
     // Read IQM header
@@ -945,17 +967,15 @@ ModelAnimation *LoadModelAnimations(const char *filename, int *animCount)
 
     if (strncmp(iqm.magic, IQM_MAGIC, sizeof(IQM_MAGIC)))
     {
-        TRACELOG(LOG_ERROR, "Magic Number \"%s\"does not match.", iqm.magic);
+        TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file is not a valid model", filename);
         fclose(iqmFile);
-
         return NULL;
     }
 
     if (iqm.version != IQM_VERSION)
     {
-        TRACELOG(LOG_ERROR, "IQM version %i is incorrect.", iqm.version);
+        TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version incorrect", filename);
         fclose(iqmFile);
-
         return NULL;
     }
 
@@ -1122,7 +1142,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
 
             Vector3 inTranslation = { 0 };
             Quaternion inRotation = { 0 };
-            Vector3 inScale = { 0 };
+            //Vector3 inScale = { 0 };      // Not used...
 
             Vector3 outTranslation = { 0 };
             Quaternion outRotation = { 0 };
@@ -1137,7 +1157,7 @@ void UpdateModelAnimation(Model model, ModelAnimation anim, int frame)
                 boneId = model.meshes[m].boneIds[boneCounter];
                 inTranslation = model.bindPose[boneId].translation;
                 inRotation = model.bindPose[boneId].rotation;
-                inScale = model.bindPose[boneId].scale;
+                //inScale = model.bindPose[boneId].scale;
                 outTranslation = anim.framePoses[frame][boneId].translation;
                 outRotation = anim.framePoses[frame][boneId].rotation;
                 outScale = anim.framePoses[frame][boneId].scale;
@@ -1818,6 +1838,11 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
 
     Vector3 scaleFactor = { size.x/mapX, size.y/255.0f, size.z/mapZ };
 
+    Vector3 vA;
+    Vector3 vB;
+    Vector3 vC;
+    Vector3 vN;
+
     for (int z = 0; z < mapZ-1; z++)
     {
         for (int x = 0; x < mapX-1; x++)
@@ -1875,14 +1900,34 @@ Mesh GenMeshHeightmap(Image heightmap, Vector3 size)
 
             // Fill normals array with data
             //--------------------------------------------------------------
-            for (int i = 0; i < 18; i += 3)
+            for (int i = 0; i < 18; i += 9)
             {
-                mesh.normals[nCounter + i] = 0.0f;
-                mesh.normals[nCounter + i + 1] = 1.0f;
-                mesh.normals[nCounter + i + 2] = 0.0f;
-            }
+                vA.x = mesh.vertices[nCounter + i];
+                vA.y = mesh.vertices[nCounter + i + 1];
+                vA.z = mesh.vertices[nCounter + i + 2];
+
+                vB.x = mesh.vertices[nCounter + i + 3];
+                vB.y = mesh.vertices[nCounter + i + 4];
+                vB.z = mesh.vertices[nCounter + i + 5];
+
+                vC.x = mesh.vertices[nCounter + i + 6];
+                vC.y = mesh.vertices[nCounter + i + 7];
+                vC.z = mesh.vertices[nCounter + i + 8];
+
+                vN = Vector3Normalize(Vector3CrossProduct(Vector3Subtract(vB, vA), Vector3Subtract(vC, vA)));
 
-            // TODO: Calculate normals in an efficient way
+                mesh.normals[nCounter + i] = vN.x;
+                mesh.normals[nCounter + i + 1] = vN.y;
+                mesh.normals[nCounter + i + 2] = vN.z;
+
+                mesh.normals[nCounter + i + 3] = vN.x;
+                mesh.normals[nCounter + i + 4] = vN.y;
+                mesh.normals[nCounter + i + 5] = vN.z;
+
+                mesh.normals[nCounter + i + 6] = vN.x;
+                mesh.normals[nCounter + i + 7] = vN.y;
+                mesh.normals[nCounter + i + 8] = vN.z;
+            }
 
             nCounter += 18;     // 6 vertex, 18 floats
             trisCounter += 2;
@@ -2293,7 +2338,7 @@ BoundingBox MeshBoundingBox(Mesh mesh)
 void MeshTangents(Mesh *mesh)
 {
     if (mesh->tangents == NULL) mesh->tangents = (float *)RL_MALLOC(mesh->vertexCount*4*sizeof(float));
-    else TRACELOG(LOG_WARNING, "Mesh tangents already exist");
+    else TRACELOG(LOG_WARNING, "MESH: Tangents data already available, re-writting");
 
     Vector3 *tan1 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
     Vector3 *tan2 = (Vector3 *)RL_MALLOC(mesh->vertexCount*sizeof(Vector3));
@@ -2366,7 +2411,7 @@ void MeshTangents(Mesh *mesh)
     // Load a new tangent attributes buffer
     mesh->vboId[LOC_VERTEX_TANGENT] = rlLoadAttribBuffer(mesh->vaoId, LOC_VERTEX_TANGENT, mesh->tangents, mesh->vertexCount*4*sizeof(float), false);
 
-    TRACELOG(LOG_INFO, "Tangents computed for mesh");
+    TRACELOG(LOG_INFO, "MESH: Tangents data computed for provided mesh");
 }
 
 // Compute mesh binormals (aka bitangent)
@@ -2794,32 +2839,20 @@ static Model LoadOBJ(const char *fileName)
     tinyobj_material_t *materials = NULL;
     unsigned int materialCount = 0;
 
-    int dataLength = 0;
-    char *data = NULL;
-
-    // Load model data
-    FILE *objFile = fopen(fileName, "rb");
+    char *fileData = LoadFileText(fileName);
 
-    if (objFile != NULL)
+    if (fileData != NULL)
     {
-        fseek(objFile, 0, SEEK_END);
-        long length = ftell(objFile);   // Get file size
-        fseek(objFile, 0, SEEK_SET);    // Reset file pointer
+        int dataSize = strlen(fileData);
+        char currentDir[1024] = { 0 };
+        strcpy(currentDir, GetWorkingDirectory());
+        chdir(GetDirectoryPath(fileName));
 
-        data = (char *)RL_MALLOC(length);
-
-        fread(data, length, 1, objFile);
-        dataLength = length;
-        fclose(objFile);
-    }
-
-    if (data != NULL)
-    {
         unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
-        int ret = tinyobj_parse_obj(&attrib, &meshes, &meshCount, &materials, &materialCount, data, dataLength, flags);
+        int ret = tinyobj_parse_obj(&attrib, &meshes, &meshCount, &materials, &materialCount, fileData, dataSize, flags);
 
-        if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "[%s] Model data could not be loaded", fileName);
-        else TRACELOG(LOG_INFO, "[%s] Model data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount);
+        if (ret != TINYOBJ_SUCCESS) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load OBJ data", fileName);
+        else TRACELOG(LOG_INFO, "MODEL: [%s] OBJ data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount);
 
         // Init model meshes array
         // TODO: Support multiple meshes... in the meantime, only one mesh is returned
@@ -2869,8 +2902,6 @@ static Model LoadOBJ(const char *fileName)
                 tinyobj_vertex_index_t idx1 = attrib.faces[3*f + 1];
                 tinyobj_vertex_index_t idx2 = attrib.faces[3*f + 2];
 
-                // TRACELOGD("Face %i index: v %i/%i/%i . vt %i/%i/%i . vn %i/%i/%i\n", f, idx0.v_idx, idx1.v_idx, idx2.v_idx, idx0.vt_idx, idx1.vt_idx, idx2.vt_idx, idx0.vn_idx, idx1.vn_idx, idx2.vn_idx);
-
                 // Fill vertices buffer (float) using vertex index of the face
                 for (int v = 0; v < 3; v++) { mesh.vertices[vCount + v] = attrib.vertices[idx0.v_idx*3 + v]; } vCount +=3;
                 for (int v = 0; v < 3; v++) { mesh.vertices[vCount + v] = attrib.vertices[idx1.v_idx*3 + v]; } vCount +=3;
@@ -2956,13 +2987,12 @@ static Model LoadOBJ(const char *fileName)
         tinyobj_attrib_free(&attrib);
         tinyobj_shapes_free(meshes, meshCount);
         tinyobj_materials_free(materials, materialCount);
+        
+        RL_FREE(fileData);
 
-        RL_FREE(data);
+        chdir(currentDir);
     }
 
-    // NOTE: At this point we have all model data loaded
-    TRACELOG(LOG_INFO, "[%s] Model loaded successfully in RAM (CPU)", fileName);
-
     return model;
 }
 #endif
@@ -3080,22 +3110,22 @@ static Model LoadIQM(const char *fileName)
 
     if (iqmFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] IQM file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open IQM file", fileName);
         return model;
     }
 
-    fread(&iqm,sizeof(IQMHeader), 1, iqmFile);  // Read IQM header
+    fread(&iqm, sizeof(IQMHeader), 1, iqmFile);  // Read IQM header
 
     if (strncmp(iqm.magic, IQM_MAGIC, sizeof(IQM_MAGIC)))
     {
-        TRACELOG(LOG_WARNING, "[%s] IQM file does not seem to be valid", fileName);
+        TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file is not a valid model", fileName);
         fclose(iqmFile);
         return model;
     }
 
     if (iqm.version != IQM_VERSION)
     {
-        TRACELOG(LOG_WARNING, "[%s] IQM file version is not supported (%i).", fileName, iqm.version);
+        TRACELOG(LOG_WARNING, "MODEL: [%s] IQM file version not supported (%i)", fileName, iqm.version);
         fclose(iqmFile);
         return model;
     }
@@ -3397,7 +3427,7 @@ static Image LoadImageFromCgltfImage(cgltf_image *image, const char *texPath, Co
             int i = 0;
             while ((image->uri[i] != ',') && (image->uri[i] != 0)) i++;
 
-            if (image->uri[i] == 0) TRACELOG(LOG_WARNING, "CGLTF Image: Invalid data URI");
+            if (image->uri[i] == 0) TRACELOG(LOG_WARNING, "IMAGE: glTF data URI is not a valid image");
             else
             {
                 int size;
@@ -3490,7 +3520,7 @@ static Model LoadGLTF(const char *fileName)
 
     if (gltfFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] glTF file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open glTF file", fileName);
         return model;
     }
 
@@ -3510,11 +3540,12 @@ static Model LoadGLTF(const char *fileName)
 
     if (result == cgltf_result_success)
     {
-        TRACELOG(LOG_INFO, "[%s][%s] Model meshes/materials: %i/%i", fileName, (data->file_type == 2)? "glb" : "gltf", data->meshes_count, data->materials_count);
+        TRACELOG(LOG_INFO, "MODEL: [%s] glTF meshes (%s) count: %i", fileName, (data->file_type == 2)? "glb" : "gltf", data->meshes_count, data->materials_count);
+        TRACELOG(LOG_INFO, "MODEL: [%s] glTF materials (%s) count: %i", fileName, (data->file_type == 2)? "glb" : "gltf", data->meshes_count, data->materials_count);
 
         // Read data buffers
         result = cgltf_load_buffers(&options, data, fileName);
-        if (result != cgltf_result_success) TRACELOG(LOG_INFO, "[%s][%s] Error loading mesh/material buffers", fileName, (data->file_type == 2)? "glb" : "gltf");
+        if (result != cgltf_result_success) TRACELOG(LOG_INFO, "MODEL: [%s] Failed to load mesh/material buffers", fileName);
 
         int primitivesCount = 0;
 
@@ -3552,8 +3583,7 @@ static Model LoadGLTF(const char *fileName)
                     UnloadImage(albedo);
                 }
 
-                //Set tint to white after it's been used by Albedo
-                tint = WHITE;
+                tint = WHITE;   // Set tint to white after it's been used by Albedo
 
                 if (data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture)
                 {
@@ -3569,8 +3599,6 @@ static Model LoadGLTF(const char *fileName)
                     UnloadImage(metallicRoughness);
                 }
 
-
-
                 if (data->materials[i].normal_texture.texture)
                 {
                     Image normalImage = LoadImageFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint);
@@ -3589,9 +3617,9 @@ static Model LoadGLTF(const char *fileName)
                 {
                     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);
+                    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);
                 }
@@ -3635,7 +3663,7 @@ static Model LoadGLTF(const char *fileName)
                         else
                         {
                             // TODO: Support normalized unsigned byte/unsigned short texture coordinates
-                            TRACELOG(LOG_WARNING, "[%s] Texture coordinates must be float", fileName);
+                            TRACELOG(LOG_WARNING, "MODEL: [%s] glTF texture coordinates must be float", fileName);
                         }
                     }
                 }
@@ -3653,7 +3681,7 @@ static Model LoadGLTF(const char *fileName)
                     else
                     {
                         // TODO: Support unsigned byte/unsigned int
-                        TRACELOG(LOG_WARNING, "[%s] Indices must be unsigned short", fileName);
+                        TRACELOG(LOG_WARNING, "MODEL: [%s] glTF index data must be unsigned short", fileName);
                     }
                 }
                 else
@@ -3678,7 +3706,7 @@ static Model LoadGLTF(const char *fileName)
 
         cgltf_free(data);
     }
-    else TRACELOG(LOG_WARNING, "[%s] glTF data could not be loaded", fileName);
+    else TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to load glTF data", fileName);
 
     RL_FREE(buffer);
 

+ 100 - 73
lib.mod/raylib/src/raudio.c

@@ -155,6 +155,9 @@ typedef struct tagBITMAPINFOHEADER {
 #endif
 #endif
 
+#define MA_MALLOC RL_MALLOC
+#define MA_FREE RL_FREE
+
 #define MA_NO_JACK
 #define MINIAUDIO_IMPLEMENTATION
 #include "external/miniaudio.h"         // miniaudio library
@@ -172,27 +175,43 @@ typedef struct tagBITMAPINFOHEADER {
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_OGG)
+    // TODO: Remap malloc()/free() calls to RL_MALLOC/RL_FREE
+
     #define STB_VORBIS_IMPLEMENTATION
     #include "external/stb_vorbis.h"    // OGG loading functions
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_XM)
+    #define JARXM_MALLOC RL_MALLOC
+    #define JARXM_FREE RL_FREE
+
     #define JAR_XM_IMPLEMENTATION
     #include "external/jar_xm.h"        // XM loading functions
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_MOD)
+    #define JARMOD_MALLOC RL_MALLOC
+    #define JARMOD_FREE RL_FREE
+
     #define JAR_MOD_IMPLEMENTATION
     #include "external/jar_mod.h"       // MOD loading functions
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_FLAC)
+    #define DRFLAC_MALLOC RL_MALLOC
+    #define DRFLAC_REALLOC RL_REALLOC
+    #define DRFLAC_FREE RL_FREE
+
     #define DR_FLAC_IMPLEMENTATION
     #define DR_FLAC_NO_WIN32_IO
     #include "external/dr_flac.h"       // FLAC loading functions
 #endif
 
 #if defined(SUPPORT_FILEFORMAT_MP3)
+    #define DRMP3_MALLOC RL_MALLOC
+    #define DRMP3_REALLOC RL_REALLOC
+    #define DRMP3_FREE RL_FREE
+
     #define DR_MP3_IMPLEMENTATION
     #include "external/dr_mp3.h"        // MP3 loading functions
 #endif
@@ -364,7 +383,7 @@ void InitAudioDevice(void)
     ma_result result = ma_context_init(NULL, 0, &ctxConfig, &AUDIO.System.context);
     if (result != MA_SUCCESS)
     {
-        TRACELOG(LOG_ERROR, "Failed to initialize audio context");
+        TRACELOG(LOG_ERROR, "AUDIO: Failed to initialize context");
         return;
     }
 
@@ -384,7 +403,7 @@ void InitAudioDevice(void)
     result = ma_device_init(&AUDIO.System.context, &config, &AUDIO.System.device);
     if (result != MA_SUCCESS)
     {
-        TRACELOG(LOG_ERROR, "Failed to initialize audio playback AUDIO.System.device");
+        TRACELOG(LOG_ERROR, "AUDIO: Failed to initialize playback device");
         ma_context_uninit(&AUDIO.System.context);
         return;
     }
@@ -394,7 +413,7 @@ void InitAudioDevice(void)
     result = ma_device_start(&AUDIO.System.device);
     if (result != MA_SUCCESS)
     {
-        TRACELOG(LOG_ERROR, "Failed to start audio playback AUDIO.System.device");
+        TRACELOG(LOG_ERROR, "AUDIO: Failed to start playback device");
         ma_device_uninit(&AUDIO.System.device);
         ma_context_uninit(&AUDIO.System.context);
         return;
@@ -404,21 +423,20 @@ void InitAudioDevice(void)
     // want to look at something a bit smarter later on to keep everything real-time, if that's necessary.
     if (ma_mutex_init(&AUDIO.System.context, &AUDIO.System.lock) != MA_SUCCESS)
     {
-        TRACELOG(LOG_ERROR, "Failed to create mutex for audio mixing");
+        TRACELOG(LOG_ERROR, "AUDIO: Failed to create mutex for mixing");
         ma_device_uninit(&AUDIO.System.device);
         ma_context_uninit(&AUDIO.System.context);
         return;
     }
 
-    TRACELOG(LOG_INFO, "Audio device initialized successfully");
-    TRACELOG(LOG_INFO, "Audio backend: miniaudio / %s", ma_get_backend_name(AUDIO.System.context.backend));
-    TRACELOG(LOG_INFO, "Audio format: %s -> %s", ma_get_format_name(AUDIO.System.device.playback.format), ma_get_format_name(AUDIO.System.device.playback.internalFormat));
-    TRACELOG(LOG_INFO, "Audio channels: %d -> %d", AUDIO.System.device.playback.channels, AUDIO.System.device.playback.internalChannels);
-    TRACELOG(LOG_INFO, "Audio sample rate: %d -> %d", AUDIO.System.device.sampleRate, AUDIO.System.device.playback.internalSampleRate);
-    TRACELOG(LOG_INFO, "Audio periods size: %d", AUDIO.System.device.playback.internalPeriodSizeInFrames*AUDIO.System.device.playback.internalPeriods);
+    TRACELOG(LOG_INFO, "AUDIO: Device initialized successfully");
+    TRACELOG(LOG_INFO, "    > Backend:      miniaudio / %s", ma_get_backend_name(AUDIO.System.context.backend));
+    TRACELOG(LOG_INFO, "    > Format:       %s -> %s", ma_get_format_name(AUDIO.System.device.playback.format), ma_get_format_name(AUDIO.System.device.playback.internalFormat));
+    TRACELOG(LOG_INFO, "    > Channels:     %d -> %d", AUDIO.System.device.playback.channels, AUDIO.System.device.playback.internalChannels);
+    TRACELOG(LOG_INFO, "    > Sample rate:  %d -> %d", AUDIO.System.device.sampleRate, AUDIO.System.device.playback.internalSampleRate);
+    TRACELOG(LOG_INFO, "    > Periods size: %d", AUDIO.System.device.playback.internalPeriodSizeInFrames*AUDIO.System.device.playback.internalPeriods);
 
     InitAudioBufferPool();
-    TRACELOG(LOG_INFO, "Audio multichannel pool size: %i", MAX_AUDIO_BUFFER_POOL_CHANNELS);
 
     AUDIO.System.isReady = true;
 }
@@ -434,9 +452,9 @@ void CloseAudioDevice(void)
 
         CloseAudioBufferPool();
 
-        TRACELOG(LOG_INFO, "Audio device closed successfully");
+        TRACELOG(LOG_INFO, "AUDIO: Device closed successfully");
     }
-    else TRACELOG(LOG_WARNING, "Could not close audio device because it is not currently initialized");
+    else TRACELOG(LOG_WARNING, "AUDIO: Device could not be closed, not currently initialized");
 }
 
 // Check if device has been initialized successfully
@@ -462,7 +480,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
 
     if (audioBuffer == NULL)
     {
-        TRACELOG(LOG_ERROR, "LoadAudioBuffer() : Failed to allocate memory for audio buffer");
+        TRACELOG(LOG_ERROR, "AUDIO: Failed to allocate memory for buffer");
         return NULL;
     }
 
@@ -476,7 +494,7 @@ AudioBuffer *LoadAudioBuffer(ma_format format, ma_uint32 channels, ma_uint32 sam
 
     if (result != MA_SUCCESS)
     {
-        TRACELOG(LOG_ERROR, "LoadAudioBuffer() : Failed to create data conversion pipeline");
+        TRACELOG(LOG_ERROR, "AUDIO: Failed to create data conversion pipeline");
         RL_FREE(audioBuffer);
         return NULL;
     }
@@ -646,7 +664,7 @@ Wave LoadWave(const char *fileName)
 #if defined(SUPPORT_FILEFORMAT_MP3)
     else if (IsFileExtension(fileName, ".mp3")) wave = LoadMP3(fileName);
 #endif
-    else TRACELOG(LOG_WARNING, "[%s] Audio fileformat not supported, it can't be loaded", fileName);
+    else TRACELOG(LOG_WARNING, "FILEIO: [%s] File format not supported", fileName);
 
     return wave;
 }
@@ -685,13 +703,13 @@ Sound LoadSoundFromWave(Wave wave)
         ma_uint32 frameCountIn = wave.sampleCount/wave.channels;
 
         ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, 0, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO_DEVICE_SAMPLE_RATE, NULL, frameCountIn, formatIn, wave.channels, wave.sampleRate);
-        if (frameCount == 0) TRACELOG(LOG_WARNING, "LoadSoundFromWave() : Failed to get frame count for format conversion");
+        if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed to get frame count for format conversion");
 
         AudioBuffer *audioBuffer = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO_DEVICE_SAMPLE_RATE, frameCount, AUDIO_BUFFER_USAGE_STATIC);
-        if (audioBuffer == NULL) TRACELOG(LOG_WARNING, "LoadSoundFromWave() : Failed to create audio buffer");
+        if (audioBuffer == NULL) TRACELOG(LOG_WARNING, "SOUND: Failed to create buffer");
 
         frameCount = (ma_uint32)ma_convert_frames(audioBuffer->data, frameCount, AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO_DEVICE_SAMPLE_RATE, wave.data, frameCountIn, formatIn, wave.channels, wave.sampleRate);
-        if (frameCount == 0) TRACELOG(LOG_WARNING, "LoadSoundFromWave() : Format conversion failed");
+        if (frameCount == 0) TRACELOG(LOG_WARNING, "SOUND: Failed format conversion");
 
         sound.sampleCount = frameCount*AUDIO_DEVICE_CHANNELS;
         sound.stream.sampleRate = AUDIO_DEVICE_SAMPLE_RATE;
@@ -708,7 +726,7 @@ void UnloadWave(Wave wave)
 {
     if (wave.data != NULL) RL_FREE(wave.data);
 
-    TRACELOG(LOG_INFO, "Unloaded wave data from RAM");
+    TRACELOG(LOG_INFO, "WAVE: Unloaded wave data from RAM");
 }
 
 // Unload sound
@@ -716,7 +734,7 @@ void UnloadSound(Sound sound)
 {
     UnloadAudioBuffer(sound.stream.buffer);
 
-    TRACELOG(LOG_INFO, "Unloaded sound data from RAM");
+    TRACELOG(LOG_INFO, "WAVE: Unloaded sound data from RAM");
 }
 
 // Update sound buffer with new data
@@ -748,8 +766,8 @@ void ExportWave(Wave wave, const char *fileName)
         success = true;
     }
 
-    if (success) TRACELOG(LOG_INFO, "Wave exported successfully: %s", fileName);
-    else TRACELOG(LOG_WARNING, "Wave could not be exported.");
+    if (success) TRACELOG(LOG_INFO, "FILEIO: [%s] Wave data exported successfully", fileName);
+    else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export wave data", fileName);
 }
 
 // Export wave sample data to code (.h)
@@ -784,10 +802,10 @@ void ExportWaveAsCode(Wave wave, const char *fileName)
 #endif
 
         fprintf(txtFile, "// Wave data information\n");
-        fprintf(txtFile, "#define %s_SAMPLE_COUNT     %d\n", varFileName, wave.sampleCount);
-        fprintf(txtFile, "#define %s_SAMPLE_RATE      %d\n", varFileName, wave.sampleRate);
-        fprintf(txtFile, "#define %s_SAMPLE_SIZE      %d\n", varFileName, wave.sampleSize);
-        fprintf(txtFile, "#define %s_CHANNELS         %d\n\n", varFileName, wave.channels);
+        fprintf(txtFile, "#define %s_SAMPLE_COUNT     %u\n", varFileName, wave.sampleCount);
+        fprintf(txtFile, "#define %s_SAMPLE_RATE      %u\n", varFileName, wave.sampleRate);
+        fprintf(txtFile, "#define %s_SAMPLE_SIZE      %u\n", varFileName, wave.sampleSize);
+        fprintf(txtFile, "#define %s_CHANNELS         %u\n\n", varFileName, wave.channels);
 
         // Write byte data as hexadecimal text
         fprintf(txtFile, "static unsigned char %s_DATA[%i] = { ", varFileName, dataSize);
@@ -830,12 +848,12 @@ void PlaySoundMulti(Sound sound)
     // If no none playing pool members can be index choose the oldest
     if (index == -1)
     {
-        TRACELOG(LOG_WARNING, "Pool age %i ended a sound early no room in buffer pool", AUDIO.MultiChannel.poolCounter);
+        TRACELOG(LOG_WARNING, "SOUND: Buffer pool is already full, count: %i", AUDIO.MultiChannel.poolCounter);
 
         if (oldIndex == -1)
         {
             // Shouldn't be able to get here... but just in case something odd happens!
-            TRACELOG(LOG_ERROR, "Sound buffer pool could not determine oldest buffer not playing sound");
+            TRACELOG(LOG_WARNING, "SOUND: Buffer pool could not determine oldest buffer not playing sound");
             return;
         }
 
@@ -930,7 +948,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
     ma_uint32 frameCount = (ma_uint32)ma_convert_frames(NULL, 0, formatOut, channels, sampleRate, NULL, frameCountIn, formatIn, wave->channels, wave->sampleRate);
     if (frameCount == 0)
     {
-        TRACELOG(LOG_WARNING, "WaveFormat() : Failed to get frame count for format conversion.");
+        TRACELOG(LOG_WARNING, "WAVE: Failed to get frame count for format conversion");
         return;
     }
 
@@ -939,7 +957,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
     frameCount = (ma_uint32)ma_convert_frames(data, frameCount, formatOut, channels, sampleRate, wave->data, frameCountIn, formatIn, wave->channels, wave->sampleRate);
     if (frameCount == 0)
     {
-        TRACELOG(LOG_WARNING, "WaveFormat() : Format conversion failed.");
+        TRACELOG(LOG_WARNING, "WAVE: Failed format conversion");
         return;
     }
 
@@ -988,7 +1006,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample)
         RL_FREE(wave->data);
         wave->data = data;
     }
-    else TRACELOG(LOG_WARNING, "Wave crop range out of bounds");
+    else TRACELOG(LOG_WARNING, "WAVE: Crop range out of bounds");
 }
 
 // Get samples data from wave as a floats array
@@ -1141,16 +1159,16 @@ Music LoadMusicStream(const char *fileName)
         else if (music.ctxType == MUSIC_MODULE_MOD) { jar_mod_unload((jar_mod_context_t *)music.ctxData); RL_FREE(music.ctxData); }
     #endif
 
-        TRACELOG(LOG_WARNING, "[%s] Music file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Music file could not be opened", fileName);
     }
     else
     {
         // Show some music stream info
-        TRACELOG(LOG_INFO, "[%s] Music file successfully loaded:", fileName);
-        TRACELOG(LOG_INFO, "   Total samples: %i", music.sampleCount);
-        TRACELOG(LOG_INFO, "   Sample rate: %i Hz", music.stream.sampleRate);
-        TRACELOG(LOG_INFO, "   Sample size: %i bits", music.stream.sampleSize);
-        TRACELOG(LOG_INFO, "   Channels: %i (%s)", music.stream.channels, (music.stream.channels == 1)? "Mono" : (music.stream.channels == 2)? "Stereo" : "Multi");
+        TRACELOG(LOG_INFO, "FILEIO: [%s] Music file successfully loaded:", fileName);
+        TRACELOG(LOG_INFO, "    > Total samples: %i", music.sampleCount);
+        TRACELOG(LOG_INFO, "    > Sample rate:   %i Hz", music.stream.sampleRate);
+        TRACELOG(LOG_INFO, "    > Sample size:   %i bits", music.stream.sampleSize);
+        TRACELOG(LOG_INFO, "    > Channels:      %i (%s)", music.stream.channels, (music.stream.channels == 1)? "Mono" : (music.stream.channels == 2)? "Stereo" : "Multi");
     }
 
     return music;
@@ -1411,9 +1429,9 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
     if (stream.buffer != NULL)
     {
         stream.buffer->looping = true;    // Always loop for streaming buffers
-        TRACELOG(LOG_INFO, "Audio stream initialized successfully (%i Hz, %i bit, %s)", stream.sampleRate, stream.sampleSize, (stream.channels == 1)? "Mono" : "Stereo");
+        TRACELOG(LOG_INFO, "STREAM: Initialized successfully (%i Hz, %i bit, %s)", stream.sampleRate, stream.sampleSize, (stream.channels == 1)? "Mono" : "Stereo");
     }
-    else TRACELOG(LOG_ERROR, "Audio stream could not be created: Failed to load audio buffer");
+    else TRACELOG(LOG_WARNING, "STREAM: Failed to load audio buffer, stream could not be created");
 
     return stream;
 }
@@ -1423,7 +1441,7 @@ void CloseAudioStream(AudioStream stream)
 {
     UnloadAudioBuffer(stream.buffer);
 
-    TRACELOG(LOG_INFO, "Unloaded audio stream data");
+    TRACELOG(LOG_INFO, "STREAM: Unloaded audio stream data from RAM");
 }
 
 // Update audio stream buffers with data
@@ -1474,9 +1492,9 @@ void UpdateAudioStream(AudioStream stream, const void *data, int samplesCount)
 
                 stream.buffer->isSubBufferProcessed[subBufferToUpdate] = false;
             }
-            else TRACELOG(LOG_ERROR, "UpdateAudioStream() : Attempting to write too many frames to buffer");
+            else TRACELOG(LOG_WARNING, "STREAM: Attempting to write too many frames to buffer");
         }
-        else TRACELOG(LOG_ERROR, "UpdateAudioStream() : Audio buffer not available for updating");
+        else TRACELOG(LOG_WARNING, "STREAM: Buffer not available for updating");
     }
 }
 
@@ -1546,7 +1564,7 @@ static void OnLog(ma_context *pContext, ma_device *pDevice, ma_uint32 logLevel,
     (void)pContext;
     (void)pDevice;
 
-    TRACELOG(LOG_ERROR, message);   // All log messages from miniaudio are errors
+    TRACELOG(LOG_ERROR, "miniaudio: %s", message);   // All log messages from miniaudio are errors
 }
 
 // Reads audio data from an AudioBuffer object in internal format.
@@ -1788,6 +1806,9 @@ static void InitAudioBufferPool(void)
     {
         AUDIO.MultiChannel.pool[i] = LoadAudioBuffer(AUDIO_DEVICE_FORMAT, AUDIO_DEVICE_CHANNELS, AUDIO_DEVICE_SAMPLE_RATE, 0, AUDIO_BUFFER_USAGE_STATIC);
     }
+    
+    // TODO: Verification required for log
+    TRACELOG(LOG_INFO, "AUDIO: Multichannel pool size: %i", MAX_AUDIO_BUFFER_POOL_CHANNELS);
 }
 
 // Close the audio buffers pool
@@ -1838,7 +1859,7 @@ static Wave LoadWAV(const char *fileName)
 
     if (wavFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] WAV file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open WAV file", fileName);
         wave.data = NULL;
     }
     else
@@ -1856,7 +1877,7 @@ static Wave LoadWAV(const char *fileName)
             (wavRiffHeader.format[2] != 'V') ||
             (wavRiffHeader.format[3] != 'E'))
         {
-            TRACELOG(LOG_WARNING, "[%s] Invalid RIFF or WAVE Header", fileName);
+            TRACELOG(LOG_WARNING, "WAVE: [%s] RIFF or WAVE header are not valid", fileName);
         }
         else
         {
@@ -1867,7 +1888,7 @@ static Wave LoadWAV(const char *fileName)
             if ((wavFormat.subChunkID[0] != 'f') || (wavFormat.subChunkID[1] != 'm') ||
                 (wavFormat.subChunkID[2] != 't') || (wavFormat.subChunkID[3] != ' '))
             {
-                TRACELOG(LOG_WARNING, "[%s] Invalid Wave format", fileName);
+                TRACELOG(LOG_WARNING, "WAVE: [%s] Wave format header is not valid", fileName);
             }
             else
             {
@@ -1881,7 +1902,7 @@ static Wave LoadWAV(const char *fileName)
                 if ((wavData.subChunkID[0] != 'd') || (wavData.subChunkID[1] != 'a') ||
                     (wavData.subChunkID[2] != 't') || (wavData.subChunkID[3] != 'a'))
                 {
-                    TRACELOG(LOG_WARNING, "[%s] Invalid data header", fileName);
+                    TRACELOG(LOG_WARNING, "WAVE: [%s] Data header is not valid", fileName);
                 }
                 else
                 {
@@ -1899,7 +1920,7 @@ static Wave LoadWAV(const char *fileName)
                     // NOTE: Only support 8 bit, 16 bit and 32 bit sample sizes
                     if ((wave.sampleSize != 8) && (wave.sampleSize != 16) && (wave.sampleSize != 32))
                     {
-                        TRACELOG(LOG_WARNING, "[%s] WAV sample size (%ibit) not supported, converted to 16bit", fileName, wave.sampleSize);
+                        TRACELOG(LOG_WARNING, "WAVE: [%s] Sample size (%ibit) not supported, converted to 16bit", fileName, wave.sampleSize);
                         WaveFormat(&wave, wave.sampleRate, 16, wave.channels);
                     }
 
@@ -1907,13 +1928,13 @@ static Wave LoadWAV(const char *fileName)
                     if (wave.channels > 2)
                     {
                         WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2);
-                        TRACELOG(LOG_WARNING, "[%s] WAV channels number (%i) not supported, converted to 2 channels", fileName, wave.channels);
+                        TRACELOG(LOG_WARNING, "WAVE: [%s] Channels number (%i) not supported, converted to 2 channels", fileName, wave.channels);
                     }
 
                     // NOTE: subChunkSize comes in bytes, we need to translate it to number of samples
                     wave.sampleCount = (wavData.subChunkSize/(wave.sampleSize/8))/wave.channels;
 
-                    TRACELOG(LOG_INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
+                    TRACELOG(LOG_INFO, "WAVE: [%s] File loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
                 }
             }
         }
@@ -1955,7 +1976,7 @@ static int SaveWAV(Wave wave, const char *fileName)
 
     FILE *wavFile = fopen(fileName, "wb");
 
-    if (wavFile == NULL) TRACELOG(LOG_WARNING, "[%s] WAV audio file could not be created", fileName);
+    if (wavFile == NULL) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open audio file", fileName);
     else
     {
         RiffHeader riffHeader;
@@ -2014,7 +2035,7 @@ static Wave LoadOGG(const char *fileName)
 
     stb_vorbis *oggFile = stb_vorbis_open_filename(fileName, NULL, NULL);
 
-    if (oggFile == NULL) TRACELOG(LOG_WARNING, "[%s] OGG file could not be opened", fileName);
+    if (oggFile == NULL) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open OGG file", fileName);
     else
     {
         stb_vorbis_info info = stb_vorbis_get_info(oggFile);
@@ -2025,13 +2046,13 @@ static Wave LoadOGG(const char *fileName)
         wave.sampleCount = (unsigned int)stb_vorbis_stream_length_in_samples(oggFile)*info.channels;  // Independent by channel
 
         float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
-        if (totalSeconds > 10) TRACELOG(LOG_WARNING, "[%s] Ogg audio length is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
+        if (totalSeconds > 10) TRACELOG(LOG_WARNING, "WAVE: [%s] Ogg audio length larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
 
         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!)
         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");
+        TRACELOG(LOG_INFO, "WAVE: [%s] OGG file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
 
         stb_vorbis_close(oggFile);
     }
@@ -2045,21 +2066,24 @@ static Wave LoadOGG(const char *fileName)
 // NOTE: Using dr_flac library
 static Wave LoadFLAC(const char *fileName)
 {
-    Wave wave;
+    Wave wave = { 0 };
 
     // Decode an entire FLAC file in one go
-    unsigned long long int totalSampleCount;
+    unsigned long long int totalSampleCount = 0;
     wave.data = drflac_open_file_and_read_pcm_frames_s16(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount);
 
-    wave.sampleCount = (unsigned int)totalSampleCount;
-    wave.sampleSize = 16;
-
-    // NOTE: Only support up to 2 channels (mono, stereo)
-    if (wave.channels > 2) TRACELOG(LOG_WARNING, "[%s] FLAC channels number (%i) not supported", fileName, wave.channels);
+    if (wave.data == NULL) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to load FLAC data", fileName);
+    else
+    {
+        wave.sampleCount = (unsigned int)totalSampleCount;
+        wave.sampleSize = 16;
 
-    if (wave.data == NULL) TRACELOG(LOG_WARNING, "[%s] FLAC data could not be loaded", fileName);
-    else TRACELOG(LOG_INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
+        // NOTE: Only support up to 2 channels (mono, stereo)
+        if (wave.channels > 2) TRACELOG(LOG_WARNING, "WAVE: [%s] FLAC channels number (%i) not supported", fileName, wave.channels);
 
+        TRACELOG(LOG_INFO, "WAVE: [%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
+    }
+ 
     return wave;
 }
 #endif
@@ -2076,17 +2100,20 @@ static Wave LoadMP3(const char *fileName)
     drmp3_config config = { 0 };
     wave.data = drmp3_open_file_and_read_f32(fileName, &config, &totalFrameCount);
 
-    wave.channels = config.outputChannels;
-    wave.sampleRate = config.outputSampleRate;
-    wave.sampleCount = (int)totalFrameCount*wave.channels;
-    wave.sampleSize = 32;
-
-    // NOTE: Only support up to 2 channels (mono, stereo)
-    if (wave.channels > 2) TRACELOG(LOG_WARNING, "[%s] MP3 channels number (%i) not supported", fileName, wave.channels);
+    if (wave.data == NULL) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to load MP3 data", fileName);
+    else
+    {
+        wave.channels = config.outputChannels;
+        wave.sampleRate = config.outputSampleRate;
+        wave.sampleCount = (int)totalFrameCount*wave.channels;
+        wave.sampleSize = 32;
 
-    if (wave.data == NULL) TRACELOG(LOG_WARNING, "[%s] MP3 data could not be loaded", fileName);
-    else TRACELOG(LOG_INFO, "[%s] MP3 file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
+        // NOTE: Only support up to 2 channels (mono, stereo)
+        if (wave.channels > 2) TRACELOG(LOG_WARNING, "WAVE: [%s] MP3 channels number (%i) not supported", fileName, wave.channels);
 
+        TRACELOG(LOG_INFO, "WAVE: [%s] MP3 file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1)? "Mono" : "Stereo");
+    }
+    
     return wave;
 }
 #endif

+ 60 - 39
lib.mod/raylib/src/raylib.h

@@ -8,7 +8,7 @@
 *       - Written in plain C code (C99) in PascalCase/camelCase notation
 *       - Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES2 - choose at compile)
 *       - Unique OpenGL abstraction layer (usable as standalone module): [rlgl]
-*       - Powerful fonts module (XNA SpriteFonts, BMFonts, TTF)
+*       - Multiple Fonts formats supported (TTF, XNA fonts, AngelCode fonts)
 *       - Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
 *       - Full 3d support for 3d Shapes, Models, Billboards, Heightmaps and more!
 *       - Flexible Materials system, supporting classic maps and PBR maps
@@ -76,15 +76,17 @@
 
 #include <stdarg.h>     // Required for: va_list - Only used by TraceLogCallback
 
-#define RLAPI           // We are building or using raylib as a static library (or Linux shared library)
-
 #if defined(_WIN32)
     // Microsoft attibutes to tell compiler that symbols are imported/exported from a .dll
     #if defined(BUILD_LIBTYPE_SHARED)
         #define RLAPI __declspec(dllexport)     // We are building raylib as a Win32 shared library (.dll)
     #elif defined(USE_LIBTYPE_SHARED)
         #define RLAPI __declspec(dllimport)     // We are using raylib as a Win32 shared library (.dll)
+    #else
+        #define RLAPI   // We are building or using raylib as a static library
     #endif
+#else
+    #define RLAPI       // We are building or using raylib as a static library (or Linux shared library)
 #endif
 
 //----------------------------------------------------------------------------------
@@ -874,6 +876,7 @@ RLAPI bool IsWindowReady(void);                                   // Check if wi
 RLAPI bool IsWindowMinimized(void);                               // Check if window has been minimized (or lost focus)
 RLAPI bool IsWindowResized(void);                                 // Check if window has been resized
 RLAPI bool IsWindowHidden(void);                                  // Check if window is currently hidden
+RLAPI bool IsWindowFullscreen(void);                              // Check if window is currently fullscreen
 RLAPI void ToggleFullscreen(void);                                // Toggle fullscreen mode (only PLATFORM_DESKTOP)
 RLAPI void UnhideWindow(void);                                    // Show the window
 RLAPI void HideWindow(void);                                      // Hide the window
@@ -950,8 +953,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 unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead);     // Load file data as byte array (read)
+RLAPI void SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write)
 RLAPI char *LoadFileText(const char *fileName);                   // Load text data from file (read), returns a '\0' terminated string
 RLAPI void SaveFileText(const char *fileName, char *text);        // Save text data to file (write), string must be '\0' terminated
 RLAPI bool FileExists(const char *fileName);                      // Check if file exists
@@ -975,8 +978,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 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 SaveStorageValue(unsigned int position, int value);    // Save integer value to storage file (to defined position)
+RLAPI int LoadStorageValue(unsigned 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)
 
@@ -1099,31 +1102,33 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve
 // Texture Loading and Drawing Functions (Module: textures)
 //------------------------------------------------------------------------------------
 
-// Image/Texture2D data loading/unloading/saving functions
+// Image loading functions
+// NOTE: This functions do not require GPU access
 RLAPI Image LoadImage(const char *fileName);                                                             // Load image from file into CPU memory (RAM)
 RLAPI Image LoadImageEx(Color *pixels, int width, int height);                                           // Load image from Color array data (RGBA - 32bit)
 RLAPI Image LoadImagePro(void *data, int width, int height, int format);                                 // Load image from raw data with parameters
 RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize);       // Load image from RAW file data
+RLAPI void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM)
 RLAPI void ExportImage(Image image, const char *fileName);                                               // Export image data to file
 RLAPI void ExportImageAsCode(Image image, const char *fileName);                                         // Export image as code file defining an array of bytes
-RLAPI Texture2D LoadTexture(const char *fileName);                                                       // Load texture from file into GPU memory (VRAM)
-RLAPI Texture2D LoadTextureFromImage(Image image);                                                       // Load texture from image data
-RLAPI TextureCubemap LoadTextureCubemap(Image image, int layoutType);                                    // Load cubemap from image, multiple image cubemap layouts supported
-RLAPI RenderTexture2D LoadRenderTexture(int width, int height);                                          // Load texture for rendering (framebuffer)
-RLAPI void UnloadImage(Image image);                                                                     // Unload image from CPU memory (RAM)
-RLAPI void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory (VRAM)
-RLAPI void UnloadRenderTexture(RenderTexture2D target);                                                  // Unload render texture from GPU memory (VRAM)
 RLAPI Color *GetImageData(Image image);                                                                  // Get pixel data from image as a Color struct array
 RLAPI Vector4 *GetImageDataNormalized(Image image);                                                      // Get pixel data from image as Vector4 array (float normalized)
-RLAPI Rectangle GetImageAlphaBorder(Image image, float threshold);                                       // Get image alpha border rectangle
-RLAPI int GetPixelDataSize(int width, int height, int format);                                           // Get pixel data size in bytes (image or texture)
-RLAPI Image GetTextureData(Texture2D texture);                                                           // Get pixel data from GPU texture and return an Image
-RLAPI Image GetScreenData(void);                                                                         // Get pixel data from screen buffer and return an Image (screenshot)
-RLAPI void UpdateTexture(Texture2D texture, const void *pixels);                                         // Update GPU texture with new data
+
+// Image generation functions
+RLAPI Image GenImageColor(int width, int height, Color color);                                           // Generate image: plain color
+RLAPI Image GenImageGradientV(int width, int height, Color top, Color bottom);                           // Generate image: vertical gradient
+RLAPI Image GenImageGradientH(int width, int height, Color left, Color right);                           // Generate image: horizontal gradient
+RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer);      // Generate image: radial gradient
+RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2);    // Generate image: checked
+RLAPI Image GenImageWhiteNoise(int width, int height, float factor);                                     // Generate image: white noise
+RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale);           // Generate image: perlin noise
+RLAPI Image GenImageCellular(int width, int height, int tileSize);                                       // Generate image: cellular algorithm. Bigger tileSize means bigger cells
 
 // Image manipulation functions
 RLAPI Image ImageCopy(Image image);                                                                      // Create an image duplicate (useful for transformations)
 RLAPI Image ImageFromImage(Image image, Rectangle rec);                                                  // Create an image from another image piece
+RLAPI Image ImageText(const char *text, int fontSize, Color color);                                      // Create an image from text (default font)
+RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint);         // Create an image from text (custom sprite font)
 RLAPI void ImageToPOT(Image *image, Color fillColor);                                                    // Convert image to POT (power-of-two)
 RLAPI void ImageFormat(Image *image, int newFormat);                                                     // Convert image data to desired format
 RLAPI void ImageAlphaMask(Image *image, Image alphaMask);                                                // Apply alpha mask to image
@@ -1136,14 +1141,6 @@ RLAPI void ImageResizeNN(Image *image, int newWidth,int newHeight);
 RLAPI void ImageResizeCanvas(Image *image, int newWidth, int newHeight, int offsetX, int offsetY, Color color);  // Resize canvas and fill with color
 RLAPI void ImageMipmaps(Image *image);                                                                   // Generate all mipmap levels for a provided image
 RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp);                            // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
-RLAPI Color *ImageExtractPalette(Image image, int maxPaletteSize, int *extractCount);                    // Extract color palette from image to maximum size (memory should be freed)
-RLAPI Image ImageText(const char *text, int fontSize, Color color);                                      // Create an image from text (default font)
-RLAPI Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint);         // Create an image from text (custom sprite font)
-RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint);             // Draw a source image within a destination image (tint applied to source)
-RLAPI void ImageDrawRectangle(Image *dst, Rectangle rec, Color color);                                   // Draw rectangle within an image
-RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color);                   // Draw rectangle lines within an image
-RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color);     // Draw text (default font) within an image (destination)
-RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color); // Draw text (custom sprite font) within an image (destination)
 RLAPI void ImageFlipVertical(Image *image);                                                              // Flip image vertically
 RLAPI void ImageFlipHorizontal(Image *image);                                                            // Flip image horizontally
 RLAPI void ImageRotateCW(Image *image);                                                                  // Rotate image clockwise 90deg
@@ -1154,23 +1151,44 @@ RLAPI void ImageColorGrayscale(Image *image);
 RLAPI void ImageColorContrast(Image *image, float contrast);                                             // Modify image color: contrast (-100 to 100)
 RLAPI void ImageColorBrightness(Image *image, int brightness);                                           // Modify image color: brightness (-255 to 255)
 RLAPI void ImageColorReplace(Image *image, Color color, Color replace);                                  // Modify image color: replace color
+RLAPI Color *ImageExtractPalette(Image image, int maxPaletteSize, int *extractCount);                    // Extract color palette from image to maximum size (memory should be freed)
+RLAPI Rectangle GetImageAlphaBorder(Image image, float threshold);                                       // Get image alpha border rectangle
 
-// Image generation functions
-RLAPI Image GenImageColor(int width, int height, Color color);                                           // Generate image: plain color
-RLAPI Image GenImageGradientV(int width, int height, Color top, Color bottom);                           // Generate image: vertical gradient
-RLAPI Image GenImageGradientH(int width, int height, Color left, Color right);                           // Generate image: horizontal gradient
-RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer);      // Generate image: radial gradient
-RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2);    // Generate image: checked
-RLAPI Image GenImageWhiteNoise(int width, int height, float factor);                                     // Generate image: white noise
-RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale);           // Generate image: perlin noise
-RLAPI Image GenImageCellular(int width, int height, int tileSize);                                       // Generate image: cellular algorithm. Bigger tileSize means bigger cells
+// Image drawing functions
+// NOTE: Image software-rendering functions (CPU)
+RLAPI void ImageClearBackground(Image *dst, Color color);                                                // Clear image background with given color
+RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color);                                  // Draw pixel within an image
+RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color);                                   // Draw pixel within an image (Vector version)
+RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image
+RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color);                          // Draw line within an image (Vector version)
+RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color);               // Draw circle within an image
+RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color);                        // Draw circle within an image (Vector version)
+RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color);       // Draw rectangle within an image
+RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color);                 // Draw rectangle within an image (Vector version)
+RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color);                                // Draw rectangle within an image 
+RLAPI void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color);                   // Draw rectangle lines within an image
+RLAPI void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color tint);             // Draw a source image within a destination image (tint applied to source)
+RLAPI void ImageDrawText(Image *dst, Vector2 position, const char *text, int fontSize, Color color);     // Draw text (default font) within an image (destination)
+RLAPI void ImageDrawTextEx(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color); // Draw text (custom sprite font) within an image (destination)
 
-// Texture2D configuration functions
+// Texture loading functions
+// NOTE: These functions require GPU access
+RLAPI Texture2D LoadTexture(const char *fileName);                                                       // Load texture from file into GPU memory (VRAM)
+RLAPI Texture2D LoadTextureFromImage(Image image);                                                       // Load texture from image data
+RLAPI TextureCubemap LoadTextureCubemap(Image image, int layoutType);                                    // Load cubemap from image, multiple image cubemap layouts supported
+RLAPI RenderTexture2D LoadRenderTexture(int width, int height);                                          // Load texture for rendering (framebuffer)
+RLAPI void UnloadTexture(Texture2D texture);                                                             // Unload texture from GPU memory (VRAM)
+RLAPI void UnloadRenderTexture(RenderTexture2D target);                                                  // Unload render texture from GPU memory (VRAM)
+RLAPI void UpdateTexture(Texture2D texture, const void *pixels);                                         // Update GPU texture with new data
+RLAPI Image GetTextureData(Texture2D texture);                                                           // Get pixel data from GPU texture and return an Image
+RLAPI Image GetScreenData(void);                                                                         // Get pixel data from screen buffer and return an Image (screenshot)
+
+// Texture configuration functions
 RLAPI void GenTextureMipmaps(Texture2D *texture);                                                        // Generate GPU mipmaps for a texture
 RLAPI void SetTextureFilter(Texture2D texture, int filterMode);                                          // Set texture scaling filter mode
 RLAPI void SetTextureWrap(Texture2D texture, int wrapMode);                                              // Set texture wrapping mode
 
-// Texture2D drawing functions
+// Texture drawing functions
 RLAPI void DrawTexture(Texture2D texture, int posX, int posY, Color tint);                               // Draw a Texture2D
 RLAPI void DrawTextureV(Texture2D texture, Vector2 position, Color tint);                                // Draw a Texture2D with position defined as Vector2
 RLAPI void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint);  // Draw a Texture2D with extended parameters
@@ -1179,6 +1197,9 @@ RLAPI void DrawTextureQuad(Texture2D texture, Vector2 tiling, Vector2 offset, Re
 RLAPI void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint);       // Draw a part of a texture defined by a rectangle with 'pro' parameters
 RLAPI void DrawTextureNPatch(Texture2D texture, NPatchInfo nPatchInfo, Rectangle destRec, Vector2 origin, float rotation, Color tint);  // Draws a texture (or part of it) that stretches or shrinks nicely
 
+// Image/Texture misc functions
+RLAPI int GetPixelDataSize(int width, int height, int format);                                           // Get pixel data size in bytes (image or texture)
+
 //------------------------------------------------------------------------------------
 // Font Loading and Text Drawing Functions (Module: text)
 //------------------------------------------------------------------------------------

+ 1 - 1
lib.mod/raylib/src/raylib.rc

@@ -15,7 +15,7 @@ BEGIN
       VALUE "InternalName", "raylib app"
       VALUE "LegalCopyright", "(c) 2020 Ramon Santamaria (@raysan5)"
       //VALUE "OriginalFilename", "raylib_app.exe"
-      VALUE "ProductName", "raylib game"
+      VALUE "ProductName", "raylib app"
       VALUE "ProductVersion", "3.0.0"
     END
   END

BIN
lib.mod/raylib/src/raylib.rc.data


+ 7 - 11
lib.mod/raylib/src/raymath.h

@@ -554,20 +554,18 @@ RMDEF float3 Vector3ToFloatV(Vector3 v)
 // Compute matrix determinant
 RMDEF float MatrixDeterminant(Matrix mat)
 {
-    float result = { 0 };
-
     // Cache the matrix values (speed optimization)
     float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
     float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
     float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
     float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
 
-    result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
-             a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
-             a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
-             a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
-             a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
-             a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
+    float result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
+                   a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
+                   a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
+                   a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
+                   a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
+                   a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
 
     return result;
 }
@@ -1323,9 +1321,7 @@ RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle
     if (fabs(q.w) > 1.0f) q = QuaternionNormalize(q);
 
     Vector3 resAxis = { 0.0f, 0.0f, 0.0f };
-    float resAngle = 0.0f;
-
-    resAngle = 2.0f*acosf(q.w);
+    float resAngle = 2.0f*acosf(q.w);
     float den = sqrtf(1.0f - q.w*q.w);
 
     if (den > 0.0001f)

+ 99 - 95
lib.mod/raylib/src/rlgl.h

@@ -650,6 +650,9 @@ RLAPI int GetPixelDataSize(int width, int height, int format);// Get pixel data
         #include <OpenGL/gl3.h>         // OpenGL 3 library for OSX
         #include <OpenGL/gl3ext.h>      // OpenGL 3 extensions library for OSX
     #else
+        #define GLAD_REALLOC RL_REALLOC
+        #define GLAD_FREE RL_FREE
+
         #define GLAD_IMPLEMENTATION
         #if defined(RLGL_STANDALONE)
             #include "glad.h"           // GLAD extensions loading library, includes OpenGL headers
@@ -940,7 +943,7 @@ void rlMatrixMode(int mode)
 // Push the current matrix into RLGL.State.stack
 void rlPushMatrix(void)
 {
-    if (RLGL.State.stackCounter >= MAX_MATRIX_STACK_SIZE) TRACELOG(LOG_ERROR, "Matrix RLGL.State.stack overflow");
+    if (RLGL.State.stackCounter >= MAX_MATRIX_STACK_SIZE) TRACELOG(LOG_ERROR, "RLGL: Matrix stack overflow (MAX_MATRIX_STACK_SIZE)");
 
     if (RLGL.State.currentMatrixMode == RL_MODELVIEW)
     {
@@ -1182,7 +1185,7 @@ void rlVertex3f(float x, float y, float z)
 
         RLGL.State.draws[RLGL.State.drawsCounter - 1].vertexCount++;
     }
-    else TRACELOG(LOG_ERROR, "MAX_BATCH_ELEMENTS overflow");
+    else TRACELOG(LOG_ERROR, "RLGL: Batch elements overflow (MAX_BATCH_ELEMENTS)");
 }
 
 // Define one vertex (position)
@@ -1310,7 +1313,7 @@ void rlTextureParameters(unsigned int id, int param, int value)
             {
 #if !defined(GRAPHICS_API_OPENGL_11)
                 if (RLGL.ExtSupported.texMirrorClamp) glTexParameteri(GL_TEXTURE_2D, param, value);
-                else TRACELOG(LOG_WARNING, "Clamp mirror wrap mode not supported");
+                else TRACELOG(LOG_WARNING, "GL: Clamp mirror wrap mode not supported (GL_MIRROR_CLAMP_EXT)");
 #endif
             }
             else glTexParameteri(GL_TEXTURE_2D, param, value);
@@ -1324,10 +1327,10 @@ void rlTextureParameters(unsigned int id, int param, int value)
             if (value <= RLGL.ExtSupported.maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
             else if (RLGL.ExtSupported.maxAnisotropicLevel > 0.0f)
             {
-                TRACELOG(LOG_WARNING, "[TEX ID %i] Maximum anisotropic filter level supported is %iX", id, RLGL.ExtSupported.maxAnisotropicLevel);
+                TRACELOG(LOG_WARNING, "GL: Maximum anisotropic filter level supported is %iX", id, RLGL.ExtSupported.maxAnisotropicLevel);
                 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
             }
-            else TRACELOG(LOG_WARNING, "Anisotropic filtering not supported");
+            else TRACELOG(LOG_WARNING, "GL: Anisotropic filtering not supported");
 #endif
         } break;
         default: break;
@@ -1416,7 +1419,7 @@ void rlDeleteRenderTextures(RenderTexture2D target)
 
     if (target.id > 0) glDeleteFramebuffers(1, &target.id);
 
-    TRACELOG(LOG_INFO, "[FBO ID %i] Unloaded render texture data from VRAM (GPU)", target.id);
+    TRACELOG(LOG_INFO, "FBO: [ID %i] Unloaded render texture data from VRAM (GPU)", target.id);
 #endif
 }
 
@@ -1435,7 +1438,7 @@ void rlDeleteVertexArrays(unsigned int id)
     if (RLGL.ExtSupported.vao)
     {
         if (id != 0) glDeleteVertexArrays(1, &id);
-        TRACELOG(LOG_INFO, "[VAO ID %i] Unloaded model data from VRAM (GPU)", id);
+        TRACELOG(LOG_INFO, "VAO: [ID %i] Unloaded vertex data from VRAM (GPU)", id);
     }
 #endif
 }
@@ -1447,7 +1450,7 @@ void rlDeleteBuffers(unsigned int id)
     if (id != 0)
     {
         glDeleteBuffers(1, &id);
-        if (!RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "[VBO ID %i] Unloaded model vertex data from VRAM (GPU)", id);
+        if (!RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "VBO: [ID %i] Unloaded vertex data from VRAM (GPU)", id);
     }
 #endif
 }
@@ -1489,30 +1492,30 @@ void rlglInit(int width, int height)
 {
     // Check OpenGL information and capabilities
     //------------------------------------------------------------------------------
-
     // Print current OpenGL and GLSL version
-    TRACELOG(LOG_INFO, "GPU: Vendor:   %s", glGetString(GL_VENDOR));
-    TRACELOG(LOG_INFO, "GPU: Renderer: %s", glGetString(GL_RENDERER));
-    TRACELOG(LOG_INFO, "GPU: Version:  %s", glGetString(GL_VERSION));
-    TRACELOG(LOG_INFO, "GPU: GLSL:     %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
+    TRACELOG(LOG_INFO, "GL: OpenGL device information:");
+    TRACELOG(LOG_INFO, "    > Vendor:   %s", glGetString(GL_VENDOR));
+    TRACELOG(LOG_INFO, "    > Renderer: %s", glGetString(GL_RENDERER));
+    TRACELOG(LOG_INFO, "    > Version:  %s", glGetString(GL_VERSION));
+    TRACELOG(LOG_INFO, "    > GLSL:     %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
 
     // NOTE: We can get a bunch of extra information about GPU capabilities (glGet*)
     //int maxTexSize;
     //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
-    //TRACELOG(LOG_INFO, "GL_MAX_TEXTURE_SIZE: %i", maxTexSize);
+    //TRACELOG(LOG_INFO, "GL: Maximum texture size: %i", maxTexSize);
 
     //GL_MAX_TEXTURE_IMAGE_UNITS
     //GL_MAX_VIEWPORT_DIMS
 
     //int numAuxBuffers;
     //glGetIntegerv(GL_AUX_BUFFERS, &numAuxBuffers);
-    //TRACELOG(LOG_INFO, "GL_AUX_BUFFERS: %i", numAuxBuffers);
+    //TRACELOG(LOG_INFO, "GL: Number of aixiliar buffers: %i", numAuxBuffers);
 
     //GLint numComp = 0;
     //GLint format[32] = { 0 };
     //glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numComp);
     //glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, format);
-    //for (int i = 0; i < numComp; i++) TRACELOG(LOG_INFO, "Supported compressed format: 0x%x", format[i]);
+    //for (int i = 0; i < numComp; i++) TRACELOG(LOG_INFO, "GL: Supported compressed format: 0x%x", format[i]);
 
     // NOTE: We don't need that much data on screen... right now...
 
@@ -1570,7 +1573,7 @@ void rlglInit(int width, int height)
     // NOTE: Duplicated string (extensionsDup) must be deallocated
 #endif
 
-    TRACELOG(LOG_INFO, "Number of supported extensions: %i", numExt);
+    TRACELOG(LOG_INFO, "GL: Supported extensions count: %i", numExt);
 
     // Show supported extensions
     //for (int i = 0; i < numExt; i++)  TRACELOG(LOG_INFO, "Supported extension: %s", extList[i]);
@@ -1645,23 +1648,23 @@ void rlglInit(int width, int height)
 #if defined(GRAPHICS_API_OPENGL_ES2)
     RL_FREE(extensionsDup);    // Duplicated string must be deallocated
 
-    if (RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "[EXTENSION] VAO extension detected, VAO functions initialized successfully");
-    else TRACELOG(LOG_WARNING, "[EXTENSION] VAO extension not found, VAO usage not supported");
+    if (RLGL.ExtSupported.vao) TRACELOG(LOG_INFO, "GL: VAO extension detected, VAO functions initialized successfully");
+    else TRACELOG(LOG_WARNING, "GL: VAO extension not found, VAO usage not supported");
 
-    if (RLGL.ExtSupported.texNPOT) TRACELOG(LOG_INFO, "[EXTENSION] NPOT textures extension detected, full NPOT textures supported");
-    else TRACELOG(LOG_WARNING, "[EXTENSION] NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
+    if (RLGL.ExtSupported.texNPOT) TRACELOG(LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported");
+    else TRACELOG(LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
 #endif
 
-    if (RLGL.ExtSupported.texCompDXT) TRACELOG(LOG_INFO, "[EXTENSION] DXT compressed textures supported");
-    if (RLGL.ExtSupported.texCompETC1) TRACELOG(LOG_INFO, "[EXTENSION] ETC1 compressed textures supported");
-    if (RLGL.ExtSupported.texCompETC2) TRACELOG(LOG_INFO, "[EXTENSION] ETC2/EAC compressed textures supported");
-    if (RLGL.ExtSupported.texCompPVRT) TRACELOG(LOG_INFO, "[EXTENSION] PVRT compressed textures supported");
-    if (RLGL.ExtSupported.texCompASTC) TRACELOG(LOG_INFO, "[EXTENSION] ASTC compressed textures supported");
+    if (RLGL.ExtSupported.texCompDXT) TRACELOG(LOG_INFO, "GL: DXT compressed textures supported");
+    if (RLGL.ExtSupported.texCompETC1) TRACELOG(LOG_INFO, "GL: ETC1 compressed textures supported");
+    if (RLGL.ExtSupported.texCompETC2) TRACELOG(LOG_INFO, "GL: ETC2/EAC compressed textures supported");
+    if (RLGL.ExtSupported.texCompPVRT) TRACELOG(LOG_INFO, "GL: PVRT compressed textures supported");
+    if (RLGL.ExtSupported.texCompASTC) TRACELOG(LOG_INFO, "GL: ASTC compressed textures supported");
 
-    if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(LOG_INFO, "[EXTENSION] Anisotropic textures filtering supported (max: %.0fX)", RLGL.ExtSupported.maxAnisotropicLevel);
-    if (RLGL.ExtSupported.texMirrorClamp) TRACELOG(LOG_INFO, "[EXTENSION] Mirror clamp wrap texture mode supported");
+    if (RLGL.ExtSupported.texAnisoFilter) TRACELOG(LOG_INFO, "GL: Anisotropic textures filtering supported (max: %.0fX)", RLGL.ExtSupported.maxAnisotropicLevel);
+    if (RLGL.ExtSupported.texMirrorClamp) TRACELOG(LOG_INFO, "GL: Mirror clamp wrap texture mode supported");
 
-    if (RLGL.ExtSupported.debugMarker) TRACELOG(LOG_INFO, "[EXTENSION] Debug Marker supported");
+    if (RLGL.ExtSupported.debugMarker) TRACELOG(LOG_INFO, "GL: Debug Marker supported");
 
     // Initialize buffers, default shaders and default textures
     //----------------------------------------------------------
@@ -1669,8 +1672,8 @@ void rlglInit(int width, int height)
     unsigned char pixels[4] = { 255, 255, 255, 255 };   // 1 pixel RGBA (4 bytes)
     RLGL.State.defaultTextureId = rlLoadTexture(pixels, 1, 1, UNCOMPRESSED_R8G8B8A8, 1);
 
-    if (RLGL.State.defaultTextureId != 0) TRACELOG(LOG_INFO, "[TEX ID %i] Base white texture loaded successfully", RLGL.State.defaultTextureId);
-    else TRACELOG(LOG_WARNING, "Base white texture could not be loaded");
+    if (RLGL.State.defaultTextureId != 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Default texture loaded successfully", RLGL.State.defaultTextureId);
+    else TRACELOG(LOG_WARNING, "TEXTURE: Failed to load default texture");
 
     // Init default Shader (customized for GL 3.3 and ES2)
     RLGL.State.defaultShader = LoadShaderDefault();
@@ -1743,7 +1746,7 @@ void rlglInit(int width, int height)
     RLGL.State.shapesTexture = GetTextureDefault();
     RLGL.State.shapesTextureRec = (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f };
 
-    TRACELOG(LOG_INFO, "OpenGL default states initialized successfully");
+    TRACELOG(LOG_INFO, "RLGL: Default state initialized successfully");
 }
 
 // Vertex Buffer Object deinitialization (memory free)
@@ -1754,7 +1757,7 @@ void rlglClose(void)
     UnloadBuffersDefault();             // Unload default buffers
     glDeleteTextures(1, &RLGL.State.defaultTextureId); // Unload default texture
 
-    TRACELOG(LOG_INFO, "[TEX ID %i] Unloaded texture data (base white texture) from VRAM", RLGL.State.defaultTextureId);
+    TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Unloaded default texture data from VRAM (GPU)", RLGL.State.defaultTextureId);
 
     RL_FREE(RLGL.State.draws);
 #endif
@@ -1820,10 +1823,10 @@ void rlLoadExtensions(void *loader)
         else TRACELOG(LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
 
         #if defined(GRAPHICS_API_OPENGL_21)
-        if (GLAD_GL_VERSION_2_1) TRACELOG(LOG_INFO, "OpenGL 2.1 profile supported");
+        if (GLAD_GL_VERSION_2_1) TRACELOG(LOG_INFO, "GL: OpenGL 2.1 profile supported");
         #elif defined(GRAPHICS_API_OPENGL_33)
-        if (GLAD_GL_VERSION_3_3) TRACELOG(LOG_INFO, "OpenGL 3.3 Core profile supported");
-        else TRACELOG(LOG_ERROR, "OpenGL 3.3 Core profile not supported");
+        if (GLAD_GL_VERSION_3_3) TRACELOG(LOG_INFO, "GL: OpenGL 3.3 Core profile supported");
+        else TRACELOG(LOG_ERROR, "GL: OpenGL 3.3 Core profile not supported");
         #endif
     #endif
 
@@ -1866,38 +1869,38 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
 #if defined(GRAPHICS_API_OPENGL_11)
     if (format >= COMPRESSED_DXT1_RGB)
     {
-        TRACELOG(LOG_WARNING, "OpenGL 1.1 does not support GPU compressed texture formats");
+        TRACELOG(LOG_WARNING, "GL: OpenGL 1.1 does not support GPU compressed texture formats");
         return id;
     }
 #else
     if ((!RLGL.ExtSupported.texCompDXT) && ((format == COMPRESSED_DXT1_RGB) || (format == COMPRESSED_DXT1_RGBA) ||
         (format == COMPRESSED_DXT3_RGBA) || (format == COMPRESSED_DXT5_RGBA)))
     {
-        TRACELOG(LOG_WARNING, "DXT compressed texture format not supported");
+        TRACELOG(LOG_WARNING, "GL: DXT compressed texture format not supported");
         return id;
     }
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     if ((!RLGL.ExtSupported.texCompETC1) && (format == COMPRESSED_ETC1_RGB))
     {
-        TRACELOG(LOG_WARNING, "ETC1 compressed texture format not supported");
+        TRACELOG(LOG_WARNING, "GL: ETC1 compressed texture format not supported");
         return id;
     }
 
     if ((!RLGL.ExtSupported.texCompETC2) && ((format == COMPRESSED_ETC2_RGB) || (format == COMPRESSED_ETC2_EAC_RGBA)))
     {
-        TRACELOG(LOG_WARNING, "ETC2 compressed texture format not supported");
+        TRACELOG(LOG_WARNING, "GL: ETC2 compressed texture format not supported");
         return id;
     }
 
     if ((!RLGL.ExtSupported.texCompPVRT) && ((format == COMPRESSED_PVRT_RGB) || (format == COMPRESSED_PVRT_RGBA)))
     {
-        TRACELOG(LOG_WARNING, "PVRT compressed texture format not supported");
+        TRACELOG(LOG_WARNING, "GL: PVRT compressed texture format not supported");
         return id;
     }
 
     if ((!RLGL.ExtSupported.texCompASTC) && ((format == COMPRESSED_ASTC_4x4_RGBA) || (format == COMPRESSED_ASTC_8x8_RGBA)))
     {
-        TRACELOG(LOG_WARNING, "ASTC compressed texture format not supported");
+        TRACELOG(LOG_WARNING, "GL: ASTC compressed texture format not supported");
         return id;
     }
 #endif
@@ -1917,7 +1920,7 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
     int mipHeight = height;
     int mipOffset = 0;          // Mipmap data offset
 
-    TRACELOGD("Load texture from data memory address: 0x%x", data);
+    TRACELOGD("TEXTURE: Load texture from data memory address: 0x%x", data);
 
     // Load the different mipmap levels
     for (int i = 0; i < mipmapCount; i++)
@@ -1927,7 +1930,7 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
         unsigned int glInternalFormat, glFormat, glType;
         rlGetGlTextureFormats(format, &glInternalFormat, &glFormat, &glType);
 
-        TRACELOGD("Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset);
+        TRACELOGD("TEXTURE: Load mipmap level %i (%i x %i), size: %i, offset: %i", i, mipWidth, mipHeight, mipSize, mipOffset);
 
         if (glInternalFormat != -1)
         {
@@ -2003,8 +2006,8 @@ unsigned int rlLoadTexture(void *data, int width, int height, int format, int mi
     // Unbind current texture
     glBindTexture(GL_TEXTURE_2D, 0);
 
-    if (id > 0) TRACELOG(LOG_INFO, "[TEX ID %i] Texture created successfully (%ix%i - %i mipmaps)", id, width, height, mipmapCount);
-    else TRACELOG(LOG_WARNING, "Texture could not be created");
+    if (id > 0) TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Texture created successfully (%ix%i - %i mipmaps)", id, width, height, mipmapCount);
+    else TRACELOG(LOG_WARNING, "TEXTURE: Failed to load texture");
 
     return id;
 }
@@ -2137,7 +2140,7 @@ void rlUpdateTexture(unsigned int id, int width, int height, int format, const v
     {
         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, glFormat, glType, (unsigned char *)data);
     }
-    else TRACELOG(LOG_WARNING, "Texture format updating not supported");
+    else TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Failed to update for current texture format (%i)", id, format);
 }
 
 // Get OpenGL internal formats and data type from raylib PixelFormat
@@ -2188,7 +2191,7 @@ void rlGetGlTextureFormats(int format, unsigned int *glInternalFormat, unsigned
         case COMPRESSED_ASTC_4x4_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; break;  // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
         case COMPRESSED_ASTC_8x8_RGBA: if (RLGL.ExtSupported.texCompASTC) *glInternalFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR; break;  // NOTE: Requires OpenGL ES 3.1 or OpenGL 4.3
         #endif
-        default: TRACELOG(LOG_WARNING, "Texture format not supported"); break;
+        default: TRACELOG(LOG_WARNING, "TEXTURE: Current format not supported (%i)", format); break;
     }
 }
 
@@ -2244,7 +2247,7 @@ RenderTexture2D rlLoadRenderTexture(int width, int height, int format, int depth
 
     // Check if fbo is complete with attachments (valid)
     //-----------------------------------------------------------------------------------------------------
-    if (rlRenderTextureComplete(target)) TRACELOG(LOG_INFO, "[FBO ID %i] Framebuffer object created successfully", target.id);
+    if (rlRenderTextureComplete(target)) TRACELOG(LOG_INFO, "FBO: [ID %i] Framebuffer object created successfully", target.id);
     //-----------------------------------------------------------------------------------------------------
 
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -2285,12 +2288,12 @@ bool rlRenderTextureComplete(RenderTexture target)
     {
         switch (status)
         {
-            case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(LOG_WARNING, "Framebuffer is unsupported"); break;
-            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(LOG_WARNING, "Framebuffer has incomplete attachment"); break;
+            case GL_FRAMEBUFFER_UNSUPPORTED: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer is unsupported", target.id); break;
+            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete attachment", target.id); break;
 #if defined(GRAPHICS_API_OPENGL_ES2)
-            case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TRACELOG(LOG_WARNING, "Framebuffer has incomplete dimensions"); break;
+            case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has incomplete dimensions", target.id); break;
 #endif
-            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TRACELOG(LOG_WARNING, "Framebuffer has a missing attachment"); break;
+            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: TRACELOG(LOG_WARNING, "FBO: [ID %i] Framebuffer has a missing attachment", target.id); break;
             default: break;
         }
     }
@@ -2348,16 +2351,15 @@ void rlGenerateMipmaps(Texture2D *texture)
             texture->mipmaps = mipmapCount + 1;
             RL_FREE(data); // Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
 
-            TRACELOG(LOG_WARNING, "[TEX ID %i] Mipmaps [%i] generated manually on CPU side", texture->id, texture->mipmaps);
+            TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Mipmaps generated manually on CPU side, total: %i", texture->id, texture->mipmaps);
         }
-        else TRACELOG(LOG_WARNING, "[TEX ID %i] Mipmaps could not be generated for texture format", texture->id);
+        else TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps for provided texture format", texture->id);
     }
 #elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
     {
         //glHint(GL_GENERATE_MIPMAP_HINT, GL_DONT_CARE);   // Hint for mipmaps generation algorythm: GL_FASTEST, GL_NICEST, GL_DONT_CARE
         glGenerateMipmap(GL_TEXTURE_2D);    // Generate mipmaps automatically
-        TRACELOG(LOG_INFO, "[TEX ID %i] Mipmaps generated automatically", texture->id);
 
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);   // Activate Trilinear filtering for mipmaps
@@ -2366,9 +2368,10 @@ void rlGenerateMipmaps(Texture2D *texture)
         #define MAX(a,b) (((a)>(b))?(a):(b))
 
         texture->mipmaps =  1 + (int)floor(log(MAX(texture->width, texture->height))/log(2));
+        TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Mipmaps generated automatically, total: %i", texture->id, texture->mipmaps);
     }
 #endif
-    else TRACELOG(LOG_WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id);
+    else TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps", texture->id);
 
     glBindTexture(GL_TEXTURE_2D, 0);
 }
@@ -2379,7 +2382,7 @@ void rlLoadMesh(Mesh *mesh, bool dynamic)
     if (mesh->vaoId > 0)
     {
         // Check if mesh has already been loaded in GPU
-        TRACELOG(LOG_WARNING, "Trying to re-load an already loaded mesh");
+        TRACELOG(LOG_WARNING, "VAO: [ID %i] Trying to re-load an already loaded mesh", mesh->vaoId);
         return;
     }
 
@@ -2492,12 +2495,12 @@ void rlLoadMesh(Mesh *mesh, bool dynamic)
 
     if (RLGL.ExtSupported.vao)
     {
-        if (mesh->vaoId > 0) TRACELOG(LOG_INFO, "[VAO ID %i] Mesh uploaded successfully to VRAM (GPU)", mesh->vaoId);
-        else TRACELOG(LOG_WARNING, "Mesh could not be uploaded to VRAM (GPU)");
+        if (mesh->vaoId > 0) TRACELOG(LOG_INFO, "VAO: [ID %i] Mesh uploaded successfully to VRAM (GPU)", mesh->vaoId);
+        else TRACELOG(LOG_WARNING, "VAO: Failed to load mesh to VRAM (GPU)");
     }
     else
     {
-        TRACELOG(LOG_INFO, "[VBOs] Mesh uploaded successfully to VRAM (GPU)");
+        TRACELOG(LOG_INFO, "VBO: Mesh uploaded successfully to VRAM (GPU)");
     }
 #endif
 }
@@ -2895,7 +2898,7 @@ void *rlReadTexturePixels(Texture2D texture)
         pixels = (unsigned char *)RL_MALLOC(size);
         glGetTexImage(GL_TEXTURE_2D, 0, glFormat, glType, pixels);
     }
-    else TRACELOG(LOG_WARNING, "Texture data retrieval not suported for pixel format");
+    else TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Data retrieval not suported for pixel format (%i)", texture.id, texture.format);
 
     glBindTexture(GL_TEXTURE_2D, 0);
 #endif
@@ -3031,7 +3034,7 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
 
         if (shader.id == 0)
         {
-            TRACELOG(LOG_WARNING, "Custom shader could not be loaded");
+            TRACELOG(LOG_WARNING, "SHADER: Failed to load custom shader code");
             shader = RLGL.State.defaultShader;
         }
 
@@ -3057,7 +3060,7 @@ Shader LoadShaderCode(const char *vsCode, const char *fsCode)
 
         name[namelen] = 0;
 
-        TRACELOGD("[SHDR ID %i] Active uniform [%s] set at location: %i", shader.id, name, glGetUniformLocation(shader.id, name));
+        TRACELOGD("SHADER: [ID %i] Active uniform (%s) set at location: %i", shader.id, name, glGetUniformLocation(shader.id, name));
     }
 #endif
 
@@ -3070,7 +3073,7 @@ void UnloadShader(Shader shader)
     if (shader.id > 0)
     {
         rlDeleteShader(shader.id);
-        TRACELOG(LOG_INFO, "[SHDR ID %i] Unloaded shader program data", shader.id);
+        TRACELOG(LOG_INFO, "SHADER: [ID %i] Unloaded shader program data from VRAM (GPU)", shader.id);
     }
 
     RL_FREE(shader.locs);
@@ -3103,8 +3106,8 @@ int GetShaderLocation(Shader shader, const char *uniformName)
 #if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
     location = glGetUniformLocation(shader.id, uniformName);
 
-    if (location == -1) TRACELOG(LOG_WARNING, "[SHDR ID %i][%s] Shader uniform could not be found", shader.id, uniformName);
-    else TRACELOG(LOG_INFO, "[SHDR ID %i][%s] Shader uniform set at location: %i", shader.id, uniformName, location);
+    if (location == -1) TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to find shader uniform: %s", shader.id, uniformName);
+    else TRACELOG(LOG_INFO, "SHADER: [ID %i] Shader uniform (%s) set at location: %i", shader.id, uniformName, location);
 #endif
     return location;
 }
@@ -3132,7 +3135,7 @@ void SetShaderValueV(Shader shader, int uniformLoc, const void *value, int unifo
         case UNIFORM_IVEC3: glUniform3iv(uniformLoc, count, (int *)value); break;
         case UNIFORM_IVEC4: glUniform4iv(uniformLoc, count, (int *)value); break;
         case UNIFORM_SAMPLER2D: glUniform1iv(uniformLoc, count, (int *)value); break;
-        default: TRACELOG(LOG_WARNING, "Shader uniform could not be set data type not recognized");
+        default: TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to set uniform, data type not recognized", shader.id);
     }
 
     //glUseProgram(0);      // Avoid reseting current shader program, in case other uniforms are set
@@ -3576,7 +3579,7 @@ void InitVrSimulator(void)
 
     RLGL.Vr.simulatorReady = true;
 #else
-    TRACELOG(LOG_WARNING, "VR Simulator not supported on OpenGL 1.1");
+    TRACELOG(LOG_WARNING, "RLGL: VR Simulator not supported on OpenGL 1.1");
 #endif
 }
 
@@ -3624,17 +3627,18 @@ void SetVrConfiguration(VrDeviceInfo hmd, Shader distortion)
                             hmd.lensDistortionValues[2]*lensRadiusSq*lensRadiusSq +
                             hmd.lensDistortionValues[3]*lensRadiusSq*lensRadiusSq*lensRadiusSq;
 
-    TRACELOGD("VR: Distortion Scale: %f", distortionScale);
+    TRACELOGD("RLGL: VR device configuration:");
+    TRACELOGD("    > Distortion Scale: %f", distortionScale);
 
     float normScreenWidth = 0.5f;
     float normScreenHeight = 1.0f;
     float scaleIn[2] = { 2.0f/normScreenWidth, 2.0f/normScreenHeight/aspect };
     float scale[2] = { normScreenWidth*0.5f/distortionScale, normScreenHeight*0.5f*aspect/distortionScale };
 
-    TRACELOGD("VR: Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
-    TRACELOGD("VR: Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
-    TRACELOGD("VR: Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
-    TRACELOGD("VR: Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
+    TRACELOGD("    > Distortion Shader: LeftLensCenter = { %f, %f }", leftLensCenter[0], leftLensCenter[1]);
+    TRACELOGD("    > Distortion Shader: RightLensCenter = { %f, %f }", rightLensCenter[0], rightLensCenter[1]);
+    TRACELOGD("    > Distortion Shader: Scale = { %f, %f }", scale[0], scale[1]);
+    TRACELOGD("    > Distortion Shader: ScaleIn = { %f, %f }", scaleIn[0], scaleIn[1]);
 
     // Fovy is normally computed with: 2*atan2f(hmd.vScreenSize, 2*hmd.eyeToScreenDistance)
     // ...but with lens distortion it is increased (see Oculus SDK Documentation)
@@ -3813,7 +3817,7 @@ static unsigned int CompileShader(const char *shaderStr, int type)
 
     if (success != GL_TRUE)
     {
-        TRACELOG(LOG_WARNING, "[SHDR ID %i] Failed to compile shader...", shader);
+        TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to compile shader code", shader);
         int maxLength = 0;
         int length;
         glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
@@ -3825,13 +3829,13 @@ static unsigned int CompileShader(const char *shaderStr, int type)
 #endif
         glGetShaderInfoLog(shader, maxLength, &length, log);
 
-        TRACELOG(LOG_INFO, "%s", log);
+        TRACELOG(LOG_WARNING, "SHADER: [ID %i] Compile error: %s", shader, log);
 
 #if defined(_MSC_VER)
         RL_FREE(log);
 #endif
     }
-    else TRACELOG(LOG_INFO, "[SHDR ID %i] Shader compiled successfully", shader);
+    else TRACELOG(LOG_INFO, "SHADER: [ID %i] Compiled successfully", shader);
 
     return shader;
 }
@@ -3867,7 +3871,7 @@ static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShad
 
     if (success == GL_FALSE)
     {
-        TRACELOG(LOG_WARNING, "[SHDR ID %i] Failed to link shader program...", program);
+        TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to link shader program", program);
 
         int maxLength = 0;
         int length;
@@ -3881,7 +3885,7 @@ static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShad
 #endif
         glGetProgramInfoLog(program, maxLength, &length, log);
 
-        TRACELOG(LOG_INFO, "%s", log);
+        TRACELOG(LOG_WARNING, "SHADER: [ID %i] Link error: %s", program, log);
 
 #if defined(_MSC_VER)
         RL_FREE(log);
@@ -3890,7 +3894,7 @@ static unsigned int LoadShaderProgram(unsigned int vShaderId, unsigned int fShad
 
         program = 0;
     }
-    else TRACELOG(LOG_INFO, "[SHDR ID %i] Shader program loaded successfully", program);
+    else TRACELOG(LOG_INFO, "SHADER: [ID %i] Program loaded successfully", program);
 #endif
     return program;
 }
@@ -3973,7 +3977,7 @@ static Shader LoadShaderDefault(void)
 
     if (shader.id > 0)
     {
-        TRACELOG(LOG_INFO, "[SHDR ID %i] Default shader loaded successfully", shader.id);
+        TRACELOG(LOG_INFO, "SHADER: [ID %i] Default shader loaded successfully", shader.id);
 
         // Set default shader locations: attributes locations
         shader.locs[LOC_VERTEX_POSITION] = glGetAttribLocation(shader.id, "vertexPosition");
@@ -3989,7 +3993,7 @@ static Shader LoadShaderDefault(void)
         // changed for external custom shaders, we just use direct bindings above
         //SetShaderDefaultLocations(&shader);
     }
-    else TRACELOG(LOG_WARNING, "[SHDR ID %i] Default shader could not be loaded", shader.id);
+    else TRACELOG(LOG_WARNING, "SHADER: [ID %i] Failed to load default shader", shader.id);
 
     return shader;
 }
@@ -4079,7 +4083,7 @@ static void LoadBuffersDefault(void)
         RLGL.State.vertexData[i].cCounter = 0;
     }
 
-    TRACELOG(LOG_INFO, "Internal buffers initialized successfully (CPU)");
+    TRACELOG(LOG_INFO, "RLGL: Internal vertex buffers initialized successfully in RAM (CPU)");
     //--------------------------------------------------------------------------------------------
 
     // Upload to GPU (VRAM) vertex data and initialize VAOs/VBOs
@@ -4125,7 +4129,7 @@ static void LoadBuffersDefault(void)
 #endif
     }
 
-    TRACELOG(LOG_INFO, "Internal buffers uploaded successfully (GPU)");
+    TRACELOG(LOG_INFO, "RLGL: Internal vertex buffers uploaded successfully to VRAM (GPU)");
 
     // Unbind the current VAO
     if (RLGL.ExtSupported.vao) glBindVertexArray(0);
@@ -4485,20 +4489,20 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight)
         if (width != 1) width /= 2;
         if (height != 1) height /= 2;
 
-        TRACELOGD("Next mipmap size: %i x %i", width, height);
+        TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);
 
         mipmapCount++;
 
         size += (width*height*4);       // Add mipmap size (in bytes)
     }
 
-    TRACELOGD("Total mipmaps required: %i", mipmapCount);
-    TRACELOGD("Total size of data required: %i", size);
+    TRACELOGD("TEXTURE: Total mipmaps required: %i", mipmapCount);
+    TRACELOGD("TEXTURE: Total size of data required: %i", size);
 
     unsigned char *temp = RL_REALLOC(data, size);
 
     if (temp != NULL) data = temp;
-    else TRACELOG(LOG_WARNING, "Mipmaps required memory could not be allocated");
+    else TRACELOG(LOG_WARNING, "TEXTURE: Failed to allocate required mipmaps memory");
 
     width = baseWidth;
     height = baseHeight;
@@ -4520,7 +4524,7 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight)
         j++;
     }
 
-    TRACELOGD("Mipmap base (%ix%i)", width, height);
+    TRACELOGD("TEXTURE: Mipmap base size (%ix%i)", width, height);
 
     for (int mip = 1; mip < mipmapCount; mip++)
     {
@@ -4591,7 +4595,7 @@ static Color *GenNextMipmap(Color *srcData, int srcWidth, int srcHeight)
         }
     }
 
-    TRACELOGD("Mipmap generated successfully (%ix%i)", width, height);
+    TRACELOGD("TEXTURE: Mipmap generated successfully (%ix%i)", width, height);
 
     return mipmap;
 }
@@ -4628,16 +4632,16 @@ char *LoadFileText(const char *fileName)
 
                 // Zero-terminate the string
                 text[count] = '\0';
-                
-                TRACELOG(LOG_INFO, "[%s] Text file loaded successfully", fileName);
+
+                TRACELOG(LOG_INFO, "FILEIO: [%s] Text file loaded successfully", fileName);
             }
-            else TRACELOG(LOG_WARNING, "[%s] Text file could not be read", fileName);
+            else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read text file", fileName);
 
             fclose(textFile);
         }
-        else TRACELOG(LOG_WARNING, "[%s] Text file could not be opened", fileName);
+        else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
     }
-    else TRACELOG(LOG_WARNING, "File name provided is not valid");
+    else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
 
     return text;
 }

+ 5 - 5
lib.mod/raylib/src/shell.html

@@ -173,8 +173,8 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB
         <div class="emscripten" id="status">Downloading...</div>
 
         <span id='controls'>
-          <span><input type="button" value="FULLSCREEN" onclick="Module.requestFullscreen(false, false)"></span>
-          <span><input type="button" id="btn-audio" value="AUDIO OFF" onclick="toggleAudio()"></span>
+          <span><input type="button" value="🖵 FULLSCREEN" onclick="Module.requestFullscreen(false, false)"></span>
+          <span><input type="button" id="btn-audio" value="🔇 SUSPEND" onclick="toggleAudio()"></span>
         </span>
 
         <div class="emscripten">
@@ -305,7 +305,7 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB
                 construct(target, args) {
                     const result = new target(...args);
                     audioContexList.push(result);
-                    if (result.state == "suspended") audioBtn.value = "AUDIO ON";
+                    if (result.state == "suspended") audioBtn.value = "🔈 RESUME";
                     return result;
                 }
             });
@@ -318,8 +318,8 @@ jwE50AGjLCVuS8Yt4H7OgZLKK5EKOsLviEWJSL/+0uMi7gLUSBseYwqEbXvSHCec1CJvZPyHCmYQffaB
                 else if (ctx.state == "running") ctx.suspend();
             });
             
-            if (resumed) audioBtn.value = "AUDIO OFF";
-            else audioBtn.value = "AUDIO ON";
+            if (resumed) audioBtn.value = "🔇 SUSPEND";
+            else audioBtn.value = "🔈 RESUME";
         }
     </script>
     {{{ SCRIPT }}}

+ 84 - 82
lib.mod/raylib/src/text.c

@@ -268,7 +268,7 @@ extern void LoadFontDefault(void)
 
     defaultFont.baseSize = (int)defaultFont.recs[0].height;
 
-    TRACELOG(LOG_INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id);
+    TRACELOG(LOG_INFO, "FONT: Default font loaded successfully");
 }
 
 // Unload raylib default font
@@ -318,7 +318,7 @@ Font LoadFont(const char *fileName)
 
     if (font.texture.id == 0)
     {
-        TRACELOG(LOG_WARNING, "[%s] Font could not be loaded, using default font", fileName);
+        TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load font texture -> Using default font", fileName);
         font = GetFontDefault();
     }
     else SetTextureFilter(font.texture, FILTER_POINT);    // By default we set point filter (best performance)
@@ -434,8 +434,6 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
         xPosToRead = charSpacing;
     }
 
-    TRACELOGD("Font data parsed correctly from image");
-
     // NOTE: We need to remove key color borders from image to avoid weird
     // artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR
     for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK;
@@ -476,8 +474,6 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
 
     font.baseSize = (int)font.recs[0].height;
 
-    TRACELOG(LOG_INFO, "Image file loaded correctly as Font");
-
     return font;
 }
 
@@ -499,92 +495,95 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c
     // Load font data (including pixel data) from TTF file
     // NOTE: Loaded information should be enough to generate
     // font image atlas, using any packaging method
-    int dataSize = 0;
+    unsigned int dataSize = 0;
     unsigned char *fileData = LoadFileData(fileName, &dataSize);
 
     if (fileData != NULL)
     {
-        // Init font for data reading
-        stbtt_fontinfo fontInfo;
-        if (!stbtt_InitFont(&fontInfo, fileData, 0)) TRACELOG(LOG_WARNING, "Failed to init font!");
+        int genFontChars = false;
+        stbtt_fontinfo fontInfo = { 0 };
 
-        // Calculate font scale factor
-        float scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize);
+        if (stbtt_InitFont(&fontInfo, fileData, 0))     // Init font for data reading
+        {
+            // Calculate font scale factor
+            float scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize);
 
-        // Calculate font basic metrics
-        // NOTE: ascent is equivalent to font baseline
-        int ascent, descent, lineGap;
-        stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);
+            // Calculate font basic metrics
+            // NOTE: ascent is equivalent to font baseline
+            int ascent, descent, lineGap;
+            stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);
 
-        // In case no chars count provided, default to 95
-        charsCount = (charsCount > 0)? charsCount : 95;
+            // In case no chars count provided, default to 95
+            charsCount = (charsCount > 0)? charsCount : 95;
 
-        // Fill fontChars in case not provided externally
-        // NOTE: By default we fill charsCount consecutevely, starting at 32 (Space)
-        int genFontChars = false;
-        if (fontChars == NULL)
-        {
-            fontChars = (int *)RL_MALLOC(charsCount*sizeof(int));
-            for (int i = 0; i < charsCount; i++) fontChars[i] = i + 32;
-            genFontChars = true;
-        }
+            // Fill fontChars in case not provided externally
+            // NOTE: By default we fill charsCount consecutevely, starting at 32 (Space)
 
-        chars = (CharInfo *)RL_MALLOC(charsCount*sizeof(CharInfo));
+            if (fontChars == NULL)
+            {
+                fontChars = (int *)RL_MALLOC(charsCount*sizeof(int));
+                for (int i = 0; i < charsCount; i++) fontChars[i] = i + 32;
+                genFontChars = true;
+            }
 
-        // NOTE: Using simple packaging, one char after another
-        for (int i = 0; i < charsCount; i++)
-        {
-            int chw = 0, chh = 0;   // Character width and height (on generation)
-            int ch = fontChars[i];  // Character value to get info for
-            chars[i].value = ch;
+            chars = (CharInfo *)RL_MALLOC(charsCount*sizeof(CharInfo));
+
+            // NOTE: Using simple packaging, one char after another
+            for (int i = 0; i < charsCount; i++)
+            {
+                int chw = 0, chh = 0;   // Character width and height (on generation)
+                int ch = fontChars[i];  // Character value to get info for
+                chars[i].value = ch;
 
-            //  Render a unicode codepoint to a bitmap
-            //      stbtt_GetCodepointBitmap()           -- allocates and returns a bitmap
-            //      stbtt_GetCodepointBitmapBox()        -- how big the bitmap must be
-            //      stbtt_MakeCodepointBitmap()          -- renders into bitmap you provide
+                //  Render a unicode codepoint to a bitmap
+                //      stbtt_GetCodepointBitmap()           -- allocates and returns a bitmap
+                //      stbtt_GetCodepointBitmapBox()        -- how big the bitmap must be
+                //      stbtt_MakeCodepointBitmap()          -- renders into bitmap you provide
 
-            if (type != FONT_SDF) chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
-            else if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
-            else chars[i].image.data = NULL;
+                if (type != FONT_SDF) chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
+                else if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
+                else chars[i].image.data = NULL;
 
-            stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
-            chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);
+                stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
+                chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);
 
-            // Load characters images
-            chars[i].image.width = chw;
-            chars[i].image.height = chh;
-            chars[i].image.mipmaps = 1;
-            chars[i].image.format = UNCOMPRESSED_GRAYSCALE;
+                // Load characters images
+                chars[i].image.width = chw;
+                chars[i].image.height = chh;
+                chars[i].image.mipmaps = 1;
+                chars[i].image.format = UNCOMPRESSED_GRAYSCALE;
 
-            chars[i].offsetY += (int)((float)ascent*scaleFactor);
+                chars[i].offsetY += (int)((float)ascent*scaleFactor);
 
-            // NOTE: We create an empty image for space character, it could be further required for atlas packing
-            if (ch == 32)
-            {
-                chars[i].image = GenImageColor(chars[i].advanceX, fontSize, BLANK);
-                ImageFormat(&chars[i].image, UNCOMPRESSED_GRAYSCALE);
-            }
+                // NOTE: We create an empty image for space character, it could be further required for atlas packing
+                if (ch == 32)
+                {
+                    chars[i].image = GenImageColor(chars[i].advanceX, fontSize, BLANK);
+                    ImageFormat(&chars[i].image, UNCOMPRESSED_GRAYSCALE);
+                }
 
-            if (type == FONT_BITMAP)
-            {
-                // Aliased bitmap (black & white) font generation, avoiding anti-aliasing
-                // NOTE: For optimum results, bitmap font should be generated at base pixel size
-                for (int p = 0; p < chw*chh; p++)
+                if (type == FONT_BITMAP)
                 {
-                    if (((unsigned char *)chars[i].image.data)[p] < BITMAP_ALPHA_THRESHOLD) ((unsigned char *)chars[i].image.data)[p] = 0;
-                    else ((unsigned char *)chars[i].image.data)[p] = 255;
+                    // Aliased bitmap (black & white) font generation, avoiding anti-aliasing
+                    // NOTE: For optimum results, bitmap font should be generated at base pixel size
+                    for (int p = 0; p < chw*chh; p++)
+                    {
+                        if (((unsigned char *)chars[i].image.data)[p] < BITMAP_ALPHA_THRESHOLD) ((unsigned char *)chars[i].image.data)[p] = 0;
+                        else ((unsigned char *)chars[i].image.data)[p] = 255;
+                    }
                 }
-            }
 
-            // Get bounding box for character (may be offset to account for chars that dip above or below the line)
-            /*
-            int chX1, chY1, chX2, chY2;
-            stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
+                // Get bounding box for character (may be offset to account for chars that dip above or below the line)
+                /*
+                int chX1, chY1, chX2, chY2;
+                stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
 
-            TRACELOGD("Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
-            TRACELOGD("Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1);
-            */
+                TRACELOGD("FONT: Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
+                TRACELOGD("FONT: Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1);
+                */
+            }
         }
+        else TRACELOG(LOG_WARNING, "FONT: Failed to process TTF font data");
 
         RL_FREE(fileData);
         if (genFontChars) RL_FREE(fontChars);
@@ -668,8 +667,6 @@ Image GenImageFontAtlas(const CharInfo *chars, Rectangle **charRecs, int charsCo
     }
     else if (packMethod == 1)  // Use Skyline rect packing algorythm (stb_pack_rect)
     {
-        TRACELOGD("Using Skyline packing algorythm!");
-
         stbrp_context *context = (stbrp_context *)RL_MALLOC(sizeof(*context));
         stbrp_node *nodes = (stbrp_node *)RL_MALLOC(charsCount*sizeof(*nodes));
 
@@ -706,7 +703,7 @@ Image GenImageFontAtlas(const CharInfo *chars, Rectangle **charRecs, int charsCo
                     }
                 }
             }
-            else TRACELOG(LOG_WARNING, "Character could not be packed: %i", i);
+            else TRACELOG(LOG_WARNING, "FONT: Failed to package character (%i)", i);
         }
 
         RL_FREE(rects);
@@ -748,7 +745,7 @@ void UnloadFont(Font font)
         RL_FREE(font.chars);
         RL_FREE(font.recs);
 
-        TRACELOGD("Unloaded sprite font data");
+        TRACELOGD("FONT: Unloaded font data from RAM and VRAM");
     }
 }
 
@@ -970,6 +967,7 @@ void DrawTextRecEx(Font font, const char *text, Rectangle rec, float fontSize, f
                 startLine = endLine;
                 endLine = -1;
                 glyphWidth = 0;
+                selectStart += lastk - k;
                 k = lastk;
 
                 state = !state;
@@ -1228,7 +1226,6 @@ char *TextReplace(char *text, const char *replace, const char *by)
 }
 
 // Insert text in a specific position, moves all text forward
-// REQUIRES: strcpy()
 // WARNING: Allocated memory should be manually freed
 char *TextInsert(const char *text, const char *insert, int position)
 {
@@ -1349,6 +1346,9 @@ const char *TextToUpper(const char *text)
         {
             buffer[i] = (char)toupper(text[i]);
             //if ((text[i] >= 'a') && (text[i] <= 'z')) buffer[i] = text[i] - 32;
+
+            // TODO: Support Utf8 diacritics!
+            //if ((text[i] >= 'à') && (text[i] <= 'ý')) buffer[i] = text[i] - 32;
         }
         else { buffer[i] = '\0'; break; }
     }
@@ -1662,7 +1662,7 @@ static Font LoadBMFont(const char *fileName)
 
     if (fntFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] FNT file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open FNT file", fileName);
         return font;
     }
 
@@ -1675,20 +1675,21 @@ static Font LoadBMFont(const char *fileName)
     searchPoint = strstr(buffer, "lineHeight");
     sscanf(searchPoint, "lineHeight=%i base=%i scaleW=%i scaleH=%i", &fontSize, &base, &texWidth, &texHeight);
 
-    TRACELOGD("[%s] Font size: %i", fileName, fontSize);
-    TRACELOGD("[%s] Font texture scale: %ix%i", fileName, texWidth, texHeight);
+    TRACELOGD("FONT: [%s] Loaded font info:", fileName);
+    TRACELOGD("    > Base size:     %i", fontSize);
+    TRACELOGD("    > Texture scale: %ix%i", texWidth, texHeight);
 
     fgets(buffer, MAX_BUFFER_SIZE, fntFile);
     searchPoint = strstr(buffer, "file");
     sscanf(searchPoint, "file=\"%128[^\"]\"", texFileName);
 
-    TRACELOGD("[%s] Font texture filename: %s", fileName, texFileName);
+    TRACELOGD("    > Texture filename: %s", texFileName);
 
     fgets(buffer, MAX_BUFFER_SIZE, fntFile);
     searchPoint = strstr(buffer, "count");
     sscanf(searchPoint, "count=%i", &charsCount);
 
-    TRACELOGD("[%s] Font num chars: %i", fileName, charsCount);
+    TRACELOGD("    > Chars count: %i", charsCount);
 
     // Compose correct path using route of .fnt file (fileName) and texFileName
     char *texPath = NULL;
@@ -1708,7 +1709,7 @@ static Font LoadBMFont(const char *fileName)
     strncat(texPath, fileName, TextLength(fileName) - TextLength(lastSlash) + 1);
     strncat(texPath, texFileName, TextLength(texFileName));
 
-    TRACELOGD("[%s] Font texture loading path: %s", fileName, texPath);
+    TRACELOGD("    > Texture loading path: %s", texPath);
 
     Image imFont = LoadImage(texPath);
 
@@ -1758,8 +1759,9 @@ static Font LoadBMFont(const char *fileName)
     {
         UnloadFont(font);
         font = GetFontDefault();
+        TRACELOG(LOG_WARNING, "FONT: [%s] Failed to load texture, reverted to default font", fileName);
     }
-    else TRACELOG(LOG_INFO, "[%s] Font loaded successfully", fileName);
+    else TRACELOG(LOG_INFO, "FONT: [%s] Font loaded successfully", fileName);
 
     return font;
 }

+ 200 - 107
lib.mod/raylib/src/textures.c

@@ -124,14 +124,20 @@
 #endif
 
 #if defined(SUPPORT_IMAGE_EXPORT)
+    #define STBIW_MALLOC RL_MALLOC
+    #define STBIW_FREE RL_FREE
+    #define STBIW_REALLOC RL_REALLOC
+
     #define STB_IMAGE_WRITE_IMPLEMENTATION
     #include "external/stb_image_write.h"   // Required for: stbi_write_*()
 #endif
 
 #if defined(SUPPORT_IMAGE_MANIPULATION)
+    #define STBIR_MALLOC(size,c) ((void)(c), RL_MALLOC(size))
+    #define STBIR_FREE(ptr,c) ((void)(c), RL_FREE(ptr))
+
     #define STB_IMAGE_RESIZE_IMPLEMENTATION
-    #include "external/stb_image_resize.h"  // Required for: stbir_resize_uint8()
-                                            // NOTE: Used for image scaling on ImageResize()
+    #include "external/stb_image_resize.h"  // Required for: stbir_resize_uint8() [ImageResize()]
 #endif
 
 #if defined(SUPPORT_IMAGE_GENERATION)
@@ -229,7 +235,7 @@ Image LoadImage(const char *fileName)
 #if defined(STBI_REQUIRED)
         // NOTE: Using stb_image to load images (Supports multiple image formats)
 
-        int dataSize = 0;
+        unsigned int dataSize = 0;
         unsigned char *fileData = LoadFileData(fileName, &dataSize);
 
         if (fileData != NULL)
@@ -252,7 +258,7 @@ Image LoadImage(const char *fileName)
     else if (IsFileExtension(fileName, ".hdr"))
     {
 #if defined(STBI_REQUIRED)
-        int dataSize = 0;
+        unsigned int dataSize = 0;
         unsigned char *fileData = LoadFileData(fileName, &dataSize);
 
         if (fileData != NULL)
@@ -267,7 +273,7 @@ Image LoadImage(const char *fileName)
             else if (comp == 4) image.format = UNCOMPRESSED_R32G32B32A32;
             else
             {
-                TRACELOG(LOG_WARNING, "[%s] HDR Image fileformat not supported", fileName);
+                TRACELOG(LOG_WARNING, "IMAGE: [%s] HDR fileformat not supported", fileName);
                 UnloadImage(image);
             }
 
@@ -291,10 +297,10 @@ Image LoadImage(const char *fileName)
 #if defined(SUPPORT_FILEFORMAT_ASTC)
     else if (IsFileExtension(fileName, ".astc")) image = LoadASTC(fileName);
 #endif
-    else TRACELOG(LOG_WARNING, "[%s] Image fileformat not supported", fileName);
+    else TRACELOG(LOG_WARNING, "IMAGE: [%s] Fileformat not supported", fileName);
 
-    if (image.data != NULL) TRACELOG(LOG_INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height);
-    else TRACELOG(LOG_WARNING, "[%s] Image could not be loaded", fileName);
+    if (image.data != NULL) TRACELOG(LOG_INFO, "IMAGE: [%s] Data loaded successfully (%ix%i)", fileName, image.width, image.height);
+    else TRACELOG(LOG_WARNING, "IMAGE: [%s] Failed to load data", fileName);
 
     return image;
 }
@@ -348,7 +354,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
 {
     Image image = { 0 };
 
-    int dataSize = 0;
+    unsigned int dataSize = 0;
     unsigned char *fileData = LoadFileData(fileName, &dataSize);
 
     if (fileData != NULL)
@@ -383,7 +389,6 @@ Texture2D LoadTexture(const char *fileName)
         texture = LoadTextureFromImage(image);
         UnloadImage(image);
     }
-    else TRACELOG(LOG_WARNING, "Texture could not be created");
 
     return texture;
 }
@@ -398,7 +403,7 @@ Texture2D LoadTextureFromImage(Image image)
     {
         texture.id = rlLoadTexture(image.data, image.width, image.height, image.format, image.mipmaps);
     }
-    else TRACELOG(LOG_WARNING, "Texture could not be loaded from Image");
+    else TRACELOG(LOG_WARNING, "IMAGE: Data is not valid to load texture");
 
     texture.width = image.width;
     texture.height = image.height;
@@ -430,7 +435,7 @@ void UnloadTexture(Texture2D texture)
     {
         rlDeleteTextures(texture.id);
 
-        TRACELOG(LOG_INFO, "[TEX ID %i] Unloaded texture data from VRAM (GPU)", texture.id);
+        TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Unloaded texture data from VRAM (GPU)", texture.id);
     }
 }
 
@@ -447,12 +452,12 @@ Color *GetImageData(Image image)
 
     Color *pixels = (Color *)RL_MALLOC(image.width*image.height*sizeof(Color));
 
-    if (image.format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Pixel data retrieval not supported for compressed image formats");
+    if (image.format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "IMAGE: Pixel data retrieval not supported for compressed image formats");
     else
     {
         if ((image.format == UNCOMPRESSED_R32) ||
             (image.format == UNCOMPRESSED_R32G32B32) ||
-            (image.format == UNCOMPRESSED_R32G32B32A32)) TRACELOG(LOG_WARNING, "32bit pixel format converted to 8bit per channel");
+            (image.format == UNCOMPRESSED_R32G32B32A32)) TRACELOG(LOG_WARNING, "IMAGE: Pixel format converted from 32bit to 8bit per channel");
 
         for (int i = 0, k = 0; i < image.width*image.height; i++)
         {
@@ -562,7 +567,7 @@ Vector4 *GetImageDataNormalized(Image image)
 {
     Vector4 *pixels = (Vector4 *)RL_MALLOC(image.width*image.height*sizeof(Vector4));
 
-    if (image.format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Pixel data retrieval not supported for compressed image formats");
+    if (image.format >= COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "IMAGE: Pixel data retrieval not supported for compressed image formats");
     else
     {
         for (int i = 0, k = 0; i < image.width*image.height; i++)
@@ -769,11 +774,11 @@ Image GetTextureData(Texture2D texture)
             // original texture format is retrieved on RPI...
             image.format = UNCOMPRESSED_R8G8B8A8;
 #endif
-            TRACELOG(LOG_INFO, "Texture pixel data obtained successfully");
+            TRACELOG(LOG_INFO, "TEXTURE: [ID %i] Pixel data retrieved successfully", texture.id);
         }
-        else TRACELOG(LOG_WARNING, "Texture pixel data could not be obtained");
+        else TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Failed to retrieve pixel data", texture.id);
     }
-    else TRACELOG(LOG_WARNING, "Compressed texture data could not be obtained");
+    else TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] Failed to retrieve compressed pixel data", texture.id);
 
     return image;
 }
@@ -837,8 +842,8 @@ void ExportImage(Image image, const char *fileName)
     RL_FREE(imgData);
 #endif
 
-    if (success != 0) TRACELOG(LOG_INFO, "Image exported successfully: %s", fileName);
-    else TRACELOG(LOG_WARNING, "Image could not be exported.");
+    if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image exported successfully", fileName);
+    else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image", fileName);
 }
 
 // Export image as code file (.h) defining an array of bytes
@@ -961,19 +966,20 @@ void ImageToPOT(Image *image, Color fillColor)
             }
         }
 
-        TRACELOG(LOG_WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
-
-        RL_FREE(pixels);                       // Free pixels data
-        RL_FREE(image->data);                  // Free old image data
+        RL_FREE(pixels);                    // Free pixels data
+        RL_FREE(image->data);               // Free old image data
 
         int format = image->format;         // Store image data format to reconvert later
 
         // NOTE: Image size changes, new width and height
         *image = LoadImageEx(pixelsPOT, potWidth, potHeight);
 
-        RL_FREE(pixelsPOT);                    // Free POT pixels data
+        RL_FREE(pixelsPOT);                 // Free POT pixels data
 
-        ImageFormat(image, format);  // Reconvert image to previous format
+        ImageFormat(image, format);         // Reconvert image to previous format
+        
+        // TODO: Verification required for log
+        TRACELOG(LOG_WARNING, "IMAGE: Converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
     }
 }
 
@@ -1151,7 +1157,7 @@ void ImageFormat(Image *image, int newFormat)
             #endif
             }
         }
-        else TRACELOG(LOG_WARNING, "Image data format is compressed, can not be converted");
+        else TRACELOG(LOG_WARNING, "IMAGE: Data format is compressed, can not be converted");
     }
 }
 
@@ -1162,11 +1168,11 @@ void ImageAlphaMask(Image *image, Image alphaMask)
 {
     if ((image->width != alphaMask.width) || (image->height != alphaMask.height))
     {
-        TRACELOG(LOG_WARNING, "Alpha mask must be same size as image");
+        TRACELOG(LOG_WARNING, "IMAGE: Alpha mask must be same size as image");
     }
     else if (image->format >= COMPRESSED_DXT1_RGB)
     {
-        TRACELOG(LOG_WARNING, "Alpha mask can not be applied to compressed data formats");
+        TRACELOG(LOG_WARNING, "IMAGE: Alpha mask can not be applied to compressed data formats");
     }
     else
     {
@@ -1326,11 +1332,11 @@ TextureCubemap LoadTextureCubemap(Image image, int layoutType)
         for (int i = 0; i < 6; i++) ImageDraw(&faces, image, faceRecs[i], (Rectangle){ 0, size*i, size, size }, WHITE);
 
         cubemap.id = rlLoadTextureCubemap(faces.data, size, faces.format);
-        if (cubemap.id == 0) TRACELOG(LOG_WARNING, "Cubemap image could not be loaded.");
+        if (cubemap.id == 0) TRACELOG(LOG_WARNING, "IMAGE: Failed to load cubemap image");
 
         UnloadImage(faces);
     }
-    else TRACELOG(LOG_WARNING, "Cubemap image layout can not be detected.");
+    else TRACELOG(LOG_WARNING, "IMAGE: Failed to detect cubemap image layout");
 
     return cubemap;
 }
@@ -1375,7 +1381,7 @@ void ImageCrop(Image *image, Rectangle crop)
         // Reformat 32bit RGBA image to original format
         ImageFormat(image, format);
     }
-    else TRACELOG(LOG_WARNING, "Image can not be cropped, crop rectangle out of bounds");
+    else TRACELOG(LOG_WARNING, "IMAGE: Failed to crop, rectangle out of bounds");
 }
 
 // Crop image depending on alpha value
@@ -1578,26 +1584,18 @@ void ImageMipmaps(Image *image)
         if (mipWidth < 1) mipWidth = 1;
         if (mipHeight < 1) mipHeight = 1;
 
-        TRACELOGD("Next mipmap level: %i x %i - current size %i", mipWidth, mipHeight, mipSize);
+        TRACELOGD("IMAGE: Next mipmap level: %i x %i - current size %i", mipWidth, mipHeight, mipSize);
 
         mipCount++;
         mipSize += GetPixelDataSize(mipWidth, mipHeight, image->format);       // Add mipmap size (in bytes)
     }
 
-    TRACELOGD("Mipmaps available: %i - Mipmaps required: %i", image->mipmaps, mipCount);
-    TRACELOGD("Mipmaps total size required: %i", mipSize);
-    TRACELOGD("Image data memory start address: 0x%x", image->data);
-
     if (image->mipmaps < mipCount)
     {
         void *temp = RL_REALLOC(image->data, mipSize);
 
-        if (temp != NULL)
-        {
-            image->data = temp;      // Assign new pointer (new size) to store mipmaps data
-            TRACELOGD("Image data memory point reallocated: 0x%x", temp);
-        }
-        else TRACELOG(LOG_WARNING, "Mipmaps required memory could not be allocated");
+        if (temp != NULL) image->data = temp;      // Assign new pointer (new size) to store mipmaps data
+        else TRACELOG(LOG_WARNING, "IMAGE: Mipmaps required memory could not be allocated");
 
         // Pointer to allocated memory point where store next mipmap level data
         unsigned char *nextmip = (unsigned char *)image->data + GetPixelDataSize(image->width, image->height, image->format);
@@ -1609,7 +1607,7 @@ void ImageMipmaps(Image *image)
 
         for (int i = 1; i < mipCount; i++)
         {
-            TRACELOGD("Gen mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip);
+            TRACELOGD("IMAGE: Generating mipmap level: %i (%i x %i) - size: %i - offset: 0x%x", i, mipWidth, mipHeight, mipSize, nextmip);
 
             ImageResize(&imCopy, mipWidth, mipHeight);  // Uses internally Mitchell cubic downscale filter
 
@@ -1629,7 +1627,7 @@ void ImageMipmaps(Image *image)
 
         UnloadImage(imCopy);
     }
-    else TRACELOG(LOG_WARNING, "Image mipmaps already available");
+    else TRACELOG(LOG_WARNING, "IMAGE: Mipmaps already available");
 }
 
 // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
@@ -1642,13 +1640,13 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
 
     if (image->format >= COMPRESSED_DXT1_RGB)
     {
-        TRACELOG(LOG_WARNING, "Compressed data formats can not be dithered");
+        TRACELOG(LOG_WARNING, "IMAGE: Compressed data formats can not be dithered");
         return;
     }
 
     if ((rBpp + gBpp + bBpp + aBpp) > 16)
     {
-        TRACELOG(LOG_WARNING, "Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported", (rBpp+gBpp+bBpp+aBpp));
+        TRACELOG(LOG_WARNING, "IMAGE: Unsupported dithering bpps (%ibpp), only 16bpp or lower modes supported", (rBpp+gBpp+bBpp+aBpp));
     }
     else
     {
@@ -1658,7 +1656,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
 
         if ((image->format != UNCOMPRESSED_R8G8B8) && (image->format != UNCOMPRESSED_R8G8B8A8))
         {
-            TRACELOG(LOG_WARNING, "Image format is already 16bpp or lower, dithering could have no effect");
+            TRACELOG(LOG_WARNING, "IMAGE: Format is already 16bpp or lower, dithering could have no effect");
         }
 
         // Define new image format, check if desired bpp match internal known format
@@ -1668,7 +1666,7 @@ void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp)
         else
         {
             image->format = 0;
-            TRACELOG(LOG_WARNING, "Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i)", (rBpp+gBpp+bBpp+aBpp), rBpp, gBpp, bBpp, aBpp);
+            TRACELOG(LOG_WARNING, "IMAGE: Unsupported dithered OpenGL internal format: %ibpp (R%iG%iB%iA%i)", (rBpp+gBpp+bBpp+aBpp), rBpp, gBpp, bBpp, aBpp);
         }
 
         // NOTE: We will store the dithered data as unsigned short (16bpp)
@@ -1782,7 +1780,7 @@ Color *ImageExtractPalette(Image image, int maxPaletteSize, int *extractCount)
                 if (palCount >= maxPaletteSize)
                 {
                     i = image.width*image.height;   // Finish palette get
-                    TRACELOG(LOG_WARNING, "Image palette is greater than %i colors!", maxPaletteSize);
+                    TRACELOG(LOG_WARNING, "IMAGE: Palette is greater than %i colors", maxPaletteSize);
                 }
             }
         }
@@ -1811,13 +1809,13 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
     if ((srcRec.x + srcRec.width) > src.width)
     {
         srcRec.width = src.width - srcRec.x;
-        TRACELOG(LOG_WARNING, "Source rectangle width out of bounds, rescaled width: %i", srcRec.width);
+        TRACELOG(LOG_WARNING, "IMAGE: Source rectangle width out of bounds, rescaled width: %i", srcRec.width);
     }
 
     if ((srcRec.y + srcRec.height) > src.height)
     {
         srcRec.height = src.height - srcRec.y;
-        TRACELOG(LOG_WARNING, "Source rectangle height out of bounds, rescaled height: %i", srcRec.height);
+        TRACELOG(LOG_WARNING, "IMAGE: Source rectangle height out of bounds, rescaled height: %i", srcRec.height);
     }
 
     Image srcCopy = ImageCopy(src);     // Make a copy of source image to work with it
@@ -1932,9 +1930,8 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
 {
     int length = strlen(text);
 
-    int index;                  // Index position in sprite font
-    int letter = 0;             // Current character
-    int positionX = 0;          // Image drawing position
+    int textOffsetX = 0;            // Image drawing position X
+    int textOffsetY = 0;            // Offset between lines (on line break '\n')
 
     // NOTE: Text image is generated at font base size, later scaled to desired font size
     Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing);
@@ -1944,36 +1941,42 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
 
     for (int i = 0; i < length; i++)
     {
-        int next = 0;
-        letter = GetNextCodepoint(&text[i], &next);
-        index = GetGlyphIndex(font, letter);
+        // Get next codepoint from byte string and glyph index in font
+        int codepointByteCount = 0;
+        int codepoint = GetNextCodepoint(&text[i], &codepointByteCount);
+        int index = GetGlyphIndex(font, codepoint);
 
-        if (letter == 0x3f) next = 1;
-        i += (next - 1);
+        // NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
+        // but we need to draw all of the bad bytes using the '?' symbol moving one byte
+        if (codepoint == 0x3f) codepointByteCount = 1;
 
-        if (letter == '\n')
+        if (codepoint == '\n')
         {
-            // TODO: Support line break
+            // NOTE: Fixed line spacing of 1.5 line-height
+            // TODO: Support custom line spacing defined by user
+            textOffsetY += (font.baseSize + font.baseSize/2);
+            textOffsetX = 0.0f;
         }
         else
         {
-            if (letter != ' ')
+            if ((codepoint != ' ') && (codepoint != '\t'))
             {
-                ImageDraw(&imText, font.chars[index].image, (Rectangle){ 0, 0, font.chars[index].image.width, font.chars[index].image.height },
-                         (Rectangle){ (float)(positionX + font.chars[index].offsetX),(float)font.chars[index].offsetY,
-                                      font.chars[index].image.width, font.chars[index].image.height }, tint);
+                Rectangle rec = { textOffsetX + font.chars[index].offsetX, textOffsetY + font.chars[index].offsetY, font.recs[index].width, font.recs[index].height };
+                ImageDraw(&imText, font.chars[index].image, (Rectangle){ 0, 0, font.chars[index].image.width, font.chars[index].image.height }, rec, tint);
             }
 
-            if (font.chars[index].advanceX == 0) positionX += (int)(font.recs[index].width + spacing);
-            else positionX += font.chars[index].advanceX + (int)spacing;
+            if (font.chars[index].advanceX == 0) textOffsetX += (int)(font.recs[index].width + spacing);
+            else textOffsetX += font.chars[index].advanceX + (int)spacing;
         }
+
+        i += (codepointByteCount - 1);   // Move text bytes counter to next codepoint
     }
 
     // Scale image depending on text size
     if (fontSize > imSize.y)
     {
         float scaleFactor = fontSize/imSize.y;
-        TRACELOG(LOG_INFO, "Image text scaled by factor: %f", scaleFactor);
+        TRACELOG(LOG_INFO, "IMAGE: Text scaled by factor: %f", scaleFactor);
 
         // Using nearest-neighbor scaling algorithm for default font
         if (font.texture.id == GetFontDefault().texture.id) ImageResizeNN(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
@@ -1984,7 +1987,19 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
 }
 
 // Draw rectangle within an image
-void ImageDrawRectangle(Image *dst, Rectangle rec, Color color)
+void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color)
+{
+    ImageDrawRectangleRec(dst, (Rectangle){ posX, posY, width, height }, color);
+}
+
+// Draw rectangle within an image (Vector version)
+void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color)
+{
+    ImageDrawRectangle(dst, position.x, position.y, size.x, size.y, color);
+}
+
+// Draw rectangle within an image
+void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color)
 {
     // Security check to avoid program crash
     if ((dst->data == NULL) || (dst->width == 0) || (dst->height == 0)) return;
@@ -1997,10 +2012,86 @@ void ImageDrawRectangle(Image *dst, Rectangle rec, Color color)
 // Draw rectangle lines within an image
 void ImageDrawRectangleLines(Image *dst, Rectangle rec, int thick, Color color)
 {
-    ImageDrawRectangle(dst, (Rectangle){ rec.x, rec.y, rec.width, thick }, color);
-    ImageDrawRectangle(dst, (Rectangle){ rec.x, rec.y + thick, thick, rec.height - thick*2 }, color);
-    ImageDrawRectangle(dst, (Rectangle){ rec.x + rec.width - thick, rec.y + thick, thick, rec.height - thick*2 }, color);
-    ImageDrawRectangle(dst, (Rectangle){ rec.x, rec.y + rec.height - thick, rec.width, thick }, color);
+    ImageDrawRectangle(dst, rec.x, rec.y, rec.width, thick, color);
+    ImageDrawRectangle(dst, rec.x, rec.y + thick, thick, rec.height - thick*2, color);
+    ImageDrawRectangle(dst, rec.x + rec.width - thick, rec.y + thick, thick, rec.height - thick*2, color);
+    ImageDrawRectangle(dst, rec.x, rec.y + rec.height - thick, rec.width, thick, color);
+}
+
+// Clear image background with given color
+void ImageClearBackground(Image *dst, Color color)
+{
+    ImageDrawRectangle(dst, 0, 0, dst->width, dst->height, color);
+}
+
+// Draw pixel within an image
+void ImageDrawPixel(Image *dst, int x, int y, Color color)
+{
+    ImageDrawRectangle(dst, x, y, 1, 1, color);
+}
+
+// Draw pixel within an image (Vector version)
+void ImageDrawPixelV(Image *dst, Vector2 position, Color color)
+{
+    ImageDrawRectangle(dst, (int)position.x, (int)position.y, 1, 1, color);
+}
+
+// Draw circle within an image
+void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color)
+{
+    int x = 0, y = radius;
+    int decesionParameter = 3 - 2*radius;
+
+    while (y >= x)
+    {
+        ImageDrawPixel(dst, centerX + x, centerY + y, color);
+        ImageDrawPixel(dst, centerX - x, centerY + y, color);
+        ImageDrawPixel(dst, centerX + x, centerY - y, color);
+        ImageDrawPixel(dst, centerX - x, centerY - y, color);
+        ImageDrawPixel(dst, centerX + y, centerY + x, color);
+        ImageDrawPixel(dst, centerX - y, centerY + x, color);
+        ImageDrawPixel(dst, centerX + y, centerY - x, color);
+        ImageDrawPixel(dst, centerX - y, centerY - x, color);
+        x++;
+
+        if (decesionParameter > 0)
+        {
+            y--;
+            decesionParameter = decesionParameter + 4*(x - y) + 10;
+        }
+        else decesionParameter = decesionParameter + 4*x + 6;
+    }
+}
+
+// Draw circle within an image (Vector version)
+void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color)
+{
+    ImageDrawCircle(dst, (int)center.x, (int)center.y, radius, color);
+}
+
+// Draw line within an image
+void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color)
+{
+    int m = 2*(endPosY - startPosY);
+    int slopeError = m - (startPosY - startPosX);
+
+    for (int x = startPosX, y = startPosY; x <= startPosY; x++)
+    {
+        ImageDrawPixel(dst, x, y, color);
+        slopeError += m;
+
+        if (slopeError >= 0)
+        {
+            y++;
+            slopeError -= 2*(startPosY - startPosX);
+        }
+    }
+}
+
+// Draw line within an image (Vector version)
+void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color)
+{
+    ImageDrawLine(dst, (int)start.x, (int)start.y, (int)end.x, (int)end.y, color);
 }
 
 // Draw text (default font) within an image (destination)
@@ -2621,7 +2712,7 @@ void SetTextureFilter(Texture2D texture, int filterMode)
             }
             else
             {
-                TRACELOG(LOG_WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id);
+                TRACELOG(LOG_WARNING, "TEXTURE: [ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id);
 
                 // RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
                 rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR);
@@ -2968,7 +3059,7 @@ static Image LoadAnimatedGIF(const char *fileName, int *frames, int **delays)
 {
     Image image = { 0 };
 
-    int dataSize = 0;
+    unsigned int dataSize = 0;
     unsigned char *fileData = LoadFileData(fileName, &dataSize);
 
     if (fileData != NULL)
@@ -3039,7 +3130,7 @@ static Image LoadDDS(const char *fileName)
 
     if (ddsFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] DDS file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open DDS file", fileName);
     }
     else
     {
@@ -3050,7 +3141,7 @@ static Image LoadDDS(const char *fileName)
 
         if ((ddsHeaderId[0] != 'D') || (ddsHeaderId[1] != 'D') || (ddsHeaderId[2] != 'S') || (ddsHeaderId[3] != ' '))
         {
-            TRACELOG(LOG_WARNING, "[%s] DDS file does not seem to be a valid image", fileName);
+            TRACELOG(LOG_WARNING, "IMAGE: [%s] DDS file not a valid image", fileName);
         }
         else
         {
@@ -3059,11 +3150,12 @@ static Image LoadDDS(const char *fileName)
             // Get the image header
             fread(&ddsHeader, sizeof(DDSHeader), 1, ddsFile);
 
-            TRACELOGD("[%s] DDS file header size: %i", fileName, sizeof(DDSHeader));
-            TRACELOGD("[%s] DDS file pixel format size: %i", fileName, ddsHeader.ddspf.size);
-            TRACELOGD("[%s] DDS file pixel format flags: 0x%x", fileName, ddsHeader.ddspf.flags);
-            TRACELOGD("[%s] DDS file format: 0x%x", fileName, ddsHeader.ddspf.fourCC);
-            TRACELOGD("[%s] DDS file bit count: 0x%x", fileName, ddsHeader.ddspf.rgbBitCount);
+            TRACELOGD("IMAGE: [%s] DDS file info:", fileName);
+            TRACELOGD("    > Header size:        %i", fileName, sizeof(DDSHeader));
+            TRACELOGD("    > Pixel format size:  %i", fileName, ddsHeader.ddspf.size);
+            TRACELOGD("    > Pixel format flags: 0x%x", fileName, ddsHeader.ddspf.flags);
+            TRACELOGD("    > File format:        0x%x", fileName, ddsHeader.ddspf.fourCC);
+            TRACELOGD("    > File bit count:     0x%x", fileName, ddsHeader.ddspf.rgbBitCount);
 
             image.width = ddsHeader.width;
             image.height = ddsHeader.height;
@@ -3118,7 +3210,7 @@ static Image LoadDDS(const char *fileName)
                     }
                 }
             }
-            if (ddsHeader.ddspf.flags == 0x40 && ddsHeader.ddspf.rgbBitCount == 24)   // DDS_RGB, no compressed
+            else if (ddsHeader.ddspf.flags == 0x40 && ddsHeader.ddspf.rgbBitCount == 24)   // DDS_RGB, no compressed
             {
                 // NOTE: not sure if this case exists...
                 image.data = (unsigned char *)RL_MALLOC(image.width*image.height*3*sizeof(unsigned char));
@@ -3153,8 +3245,6 @@ static Image LoadDDS(const char *fileName)
                 if (ddsHeader.mipmapCount > 1) size = ddsHeader.pitchOrLinearSize*2;
                 else size = ddsHeader.pitchOrLinearSize;
 
-                TRACELOGD("Pitch or linear size: %i", ddsHeader.pitchOrLinearSize);
-
                 image.data = (unsigned char *)RL_MALLOC(size*sizeof(unsigned char));
 
                 fread(image.data, size, 1, ddsFile);
@@ -3219,7 +3309,7 @@ static Image LoadPKM(const char *fileName)
 
     if (pkmFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] PKM file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open PKM file", fileName);
     }
     else
     {
@@ -3230,7 +3320,7 @@ static Image LoadPKM(const char *fileName)
 
         if ((pkmHeader.id[0] != 'P') || (pkmHeader.id[1] != 'K') || (pkmHeader.id[2] != 'M') || (pkmHeader.id[3] != ' '))
         {
-            TRACELOG(LOG_WARNING, "[%s] PKM file does not seem to be a valid image", fileName);
+            TRACELOG(LOG_WARNING, "IMAGE: [%s] PKM file not a valid image", fileName);
         }
         else
         {
@@ -3239,9 +3329,10 @@ static Image LoadPKM(const char *fileName)
             pkmHeader.width = ((pkmHeader.width & 0x00FF) << 8) | ((pkmHeader.width & 0xFF00) >> 8);
             pkmHeader.height = ((pkmHeader.height & 0x00FF) << 8) | ((pkmHeader.height & 0xFF00) >> 8);
 
-            TRACELOGD("PKM (ETC) image width: %i", pkmHeader.width);
-            TRACELOGD("PKM (ETC) image height: %i", pkmHeader.height);
-            TRACELOGD("PKM (ETC) image format: %i", pkmHeader.format);
+            TRACELOGD("IMAGE: [%s] PKM file info:", fileName);
+            TRACELOGD("    > Image width:  %i", pkmHeader.width);
+            TRACELOGD("    > Image height: %i", pkmHeader.height);
+            TRACELOGD("    > Image format: %i", pkmHeader.format);
 
             image.width = pkmHeader.width;
             image.height = pkmHeader.height;
@@ -3312,7 +3403,7 @@ static Image LoadKTX(const char *fileName)
 
     if (ktxFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] KTX image file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to load KTX file", fileName);
     }
     else
     {
@@ -3324,7 +3415,7 @@ static Image LoadKTX(const char *fileName)
         if ((ktxHeader.id[1] != 'K') || (ktxHeader.id[2] != 'T') || (ktxHeader.id[3] != 'X') ||
             (ktxHeader.id[4] != ' ') || (ktxHeader.id[5] != '1') || (ktxHeader.id[6] != '1'))
         {
-            TRACELOG(LOG_WARNING, "[%s] KTX file does not seem to be a valid file", fileName);
+            TRACELOG(LOG_WARNING, "IMAGE: [%s] KTX file not a valid image", fileName);
         }
         else
         {
@@ -3332,9 +3423,10 @@ static Image LoadKTX(const char *fileName)
             image.height = ktxHeader.height;
             image.mipmaps = ktxHeader.mipmapLevels;
 
-            TRACELOGD("KTX (ETC) image width: %i", ktxHeader.width);
-            TRACELOGD("KTX (ETC) image height: %i", ktxHeader.height);
-            TRACELOGD("KTX (ETC) image format: 0x%x", ktxHeader.glInternalFormat);
+            TRACELOGD("IMAGE: [%s] KTX file info:", fileName);
+            TRACELOGD("    > Image width:  %i", ktxHeader.width);
+            TRACELOGD("    > Image height: %i", ktxHeader.height);
+            TRACELOGD("    > Image format: 0x%x", ktxHeader.glInternalFormat);
 
             unsigned char unused;
 
@@ -3394,7 +3486,7 @@ static int SaveKTX(Image image, const char *fileName)
 
     FILE *ktxFile = fopen(fileName, "wb");
 
-    if (ktxFile == NULL) TRACELOG(LOG_WARNING, "[%s] KTX image file could not be created", fileName);
+    if (ktxFile == NULL) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open KTX file", fileName);
     else
     {
         KTXHeader ktxHeader = { 0 };
@@ -3426,7 +3518,7 @@ static int SaveKTX(Image image, const char *fileName)
 
         // NOTE: We can save into a .ktx all PixelFormats supported by raylib, including compressed formats like DXT, ETC or ASTC
 
-        if (ktxHeader.glFormat == -1) TRACELOG(LOG_WARNING, "Image format not supported for KTX export.");
+        if (ktxHeader.glFormat == -1) TRACELOG(LOG_WARNING, "IMAGE: GL format not supported for KTX export (%i)", ktxHeader.glFormat);
         else
         {
             success = fwrite(&ktxHeader, sizeof(KTXHeader), 1, ktxFile);
@@ -3521,7 +3613,7 @@ static Image LoadPVR(const char *fileName)
 
     if (pvrFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] PVR file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to load PVR file", fileName);
     }
     else
     {
@@ -3540,7 +3632,7 @@ static Image LoadPVR(const char *fileName)
 
             if ((pvrHeader.id[0] != 'P') || (pvrHeader.id[1] != 'V') || (pvrHeader.id[2] != 'R') || (pvrHeader.id[3] != 3))
             {
-                TRACELOG(LOG_WARNING, "[%s] PVR file does not seem to be a valid image", fileName);
+                TRACELOG(LOG_WARNING, "IMAGE: [%s] PVR file not a valid image", fileName);
             }
             else
             {
@@ -3601,7 +3693,7 @@ static Image LoadPVR(const char *fileName)
                 fread(image.data, dataSize, 1, pvrFile);
             }
         }
-        else if (pvrVersion == 52) TRACELOG(LOG_INFO, "PVR v2 not supported, update your files to PVR v3");
+        else if (pvrVersion == 52) TRACELOG(LOG_INFO, "IMAGE: [%s] PVRv2 format not supported, update your files to PVRv3", fileName);
 
         fclose(pvrFile);    // Close file pointer
     }
@@ -3639,7 +3731,7 @@ static Image LoadASTC(const char *fileName)
 
     if (astcFile == NULL)
     {
-        TRACELOG(LOG_WARNING, "[%s] ASTC file could not be opened", fileName);
+        TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to load ASTC file", fileName);
     }
     else
     {
@@ -3650,7 +3742,7 @@ static Image LoadASTC(const char *fileName)
 
         if ((astcHeader.id[3] != 0x5c) || (astcHeader.id[2] != 0xa1) || (astcHeader.id[1] != 0xab) || (astcHeader.id[0] != 0x13))
         {
-            TRACELOG(LOG_WARNING, "[%s] ASTC file does not seem to be a valid image", fileName);
+            TRACELOG(LOG_WARNING, "IMAGE: [%s] ASTC file not a valid image", fileName);
         }
         else
         {
@@ -3658,9 +3750,10 @@ static Image LoadASTC(const char *fileName)
             image.width = 0x00000000 | ((int)astcHeader.width[2] << 16) | ((int)astcHeader.width[1] << 8) | ((int)astcHeader.width[0]);
             image.height = 0x00000000 | ((int)astcHeader.height[2] << 16) | ((int)astcHeader.height[1] << 8) | ((int)astcHeader.height[0]);
 
-            TRACELOGD("ASTC image width: %i", image.width);
-            TRACELOGD("ASTC image height: %i", image.height);
-            TRACELOGD("ASTC image blocks: %ix%i", astcHeader.blockX, astcHeader.blockY);
+            TRACELOGD("IMAGE: [%s] ASTC file info:", fileName);
+            TRACELOGD("    > Image width:  %i", image.width);
+            TRACELOGD("    > Image height: %i", image.height);
+            TRACELOGD("    > Image blocks: %ix%i", astcHeader.blockX, astcHeader.blockY);
 
             image.mipmaps = 1;      // NOTE: ASTC format only contains one mipmap level
 
@@ -3678,7 +3771,7 @@ static Image LoadASTC(const char *fileName)
                 if (bpp == 8) image.format = COMPRESSED_ASTC_4x4_RGBA;
                 else if (bpp == 2) image.format = COMPRESSED_ASTC_8x8_RGBA;
             }
-            else TRACELOG(LOG_WARNING, "[%s] ASTC block size configuration not supported", fileName);
+            else TRACELOG(LOG_WARNING, "IMAGE: [%s] ASTC block size configuration not supported", fileName);
         }
 
         fclose(astcFile);

+ 47 - 33
lib.mod/raylib/src/utils.c

@@ -65,6 +65,7 @@ static TraceLogCallback logCallback = NULL;             // Log callback function
 
 #if defined(PLATFORM_ANDROID)
 static AAssetManager *assetManager = NULL;              // Android assets manager pointer
+static const char *internalDataPath = NULL;             // Android internal data path
 #endif
 
 #if defined(PLATFORM_UWP)
@@ -164,7 +165,7 @@ void TraceLog(int logType, const char *text, ...)
 }
 
 // Load data from file into a buffer
-unsigned char *LoadFileData(const char *fileName, int *bytesRead)
+unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead)
 {
     unsigned char *data = NULL;
     *bytesRead = 0;
@@ -186,25 +187,25 @@ unsigned char *LoadFileData(const char *fileName, int *bytesRead)
                 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);
+                unsigned int count = fread(data, sizeof(unsigned char), size, file);
                 *bytesRead = count;
 
-                if (count != size) TRACELOG(LOG_WARNING, "[%s] File partially loaded", fileName);
-                else TRACELOG(LOG_INFO, "[%s] File loaded successfully", fileName);
+                if (count != size) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially loaded", fileName);
+                else TRACELOG(LOG_INFO, "FILEIO: [%s] File loaded successfully", fileName);
             }
-            else TRACELOG(LOG_WARNING, "[%s] File could not be read", fileName);
+            else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read file", fileName);
 
             fclose(file);
         }
-        else TRACELOG(LOG_WARNING, "[%s] File could not be opened", fileName);
+        else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
     }
-    else TRACELOG(LOG_WARNING, "File name provided is not valid");
+    else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
 
     return data;
 }
 
 // Save data to file from buffer
-void SaveFileData(const char *fileName, void *data, int bytesToWrite)
+void SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite)
 {
     if (fileName != NULL)
     {
@@ -212,17 +213,17 @@ void SaveFileData(const char *fileName, void *data, int bytesToWrite)
 
         if (file != NULL)
         {
-            int count = fwrite(data, sizeof(unsigned char), bytesToWrite, file);
+            unsigned 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);
-            else TRACELOG(LOG_INFO, "[%s] File successfully saved", fileName);
+            if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write file", fileName);
+            else if (count != bytesToWrite) TRACELOG(LOG_WARNING, "FILEIO: [%s] File partially written", fileName);
+            else TRACELOG(LOG_INFO, "FILEIO: [%s] File saved successfully", fileName);
 
             fclose(file);
         }
-        else TRACELOG(LOG_WARNING, "[%s] File could not be opened", fileName);
+        else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open file", fileName);
     }
-    else TRACELOG(LOG_WARNING, "File name provided is not valid");
+    else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
 }
 
 // Load text data from file, returns a '\0' terminated string
@@ -255,16 +256,16 @@ char *LoadFileText(const char *fileName)
 
                 // Zero-terminate the string
                 text[count] = '\0';
-                
-                TRACELOG(LOG_INFO, "[%s] Text file loaded successfully", fileName);
+
+                TRACELOG(LOG_INFO, "FILEIO: [%s] Text file loaded successfully", fileName);
             }
-            else TRACELOG(LOG_WARNING, "[%s] Text file could not be read", fileName);
+            else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to read text file", fileName);
 
             fclose(textFile);
         }
-        else TRACELOG(LOG_WARNING, "[%s] Text file could not be opened", fileName);
+        else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
     }
-    else TRACELOG(LOG_WARNING, "File name provided is not valid");
+    else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
 
     return text;
 }
@@ -280,33 +281,46 @@ void SaveFileText(const char *fileName, char *text)
         {
             int count = fprintf(file, "%s", text);
 
-            if (count == 0) TRACELOG(LOG_WARNING, "[%s] Text file could not be written", fileName);
-            else TRACELOG(LOG_INFO, "[%s] Text file successfully saved", fileName);
+            if (count == 0) TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to write text file", fileName);
+            else TRACELOG(LOG_INFO, "FILEIO: [%s] Text file saved successfully", fileName);
 
             fclose(file);
         }
-        else TRACELOG(LOG_WARNING, "[%s] Text file could not be opened", fileName);
+        else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to open text file", fileName);
     }
-    else TRACELOG(LOG_WARNING, "File name provided is not valid");
+    else TRACELOG(LOG_WARNING, "FILEIO: File name provided is not valid");
 }
 
 #if defined(PLATFORM_ANDROID)
 // Initialize asset manager from android app
-void InitAssetManager(AAssetManager *manager)
+void InitAssetManager(AAssetManager *manager, const char *dataPath)
 {
     assetManager = manager;
+    internalDataPath = dataPath;
 }
 
 // Replacement for fopen
+// Ref: https://developer.android.com/ndk/reference/group/asset
 FILE *android_fopen(const char *fileName, const char *mode)
 {
-    if (mode[0] == 'w') return NULL;
-
-    AAsset *asset = AAssetManager_open(assetManager, fileName, 0);
-
-    if (!asset) return NULL;
+    if (mode[0] == 'w')     // TODO: Test!
+    {
+        // TODO: fopen() is mapped to android_fopen() that only grants read access
+        // to assets directory through AAssetManager but we want to also be able to
+        // write data when required using the standard stdio FILE access functions
+        // Ref: https://stackoverflow.com/questions/11294487/android-writing-saving-files-from-native-code-only
+        #undef fopen
+        return fopen(TextFormat("%s/%s", internalDataPath, fileName), mode);
+        #define fopen(name, mode) android_fopen(name, mode)
+    }
+    else
+    {
+        // NOTE: AAsset provides access to read-only asset
+        AAsset *asset = AAssetManager_open(assetManager, fileName, AASSET_MODE_UNKNOWN);
 
-    return funopen(asset, android_read, android_write, android_seek, android_close);
+        if (asset != NULL) return funopen(asset, android_read, android_write, android_seek, android_close);
+        else return NULL;
+    }
 }
 #endif  // PLATFORM_ANDROID
 
@@ -321,7 +335,7 @@ static int android_read(void *cookie, char *buf, int size)
 
 static int android_write(void *cookie, const char *buf, int size)
 {
-    TRACELOG(LOG_ERROR, "Can't provide write access to the APK");
+    TRACELOG(LOG_WARNING, "ANDROID: Failed to provide write access to APK");
 
     return EACCES;
 }
@@ -378,7 +392,7 @@ void UWPSendMessage(UWPMessage *msg)
         UWPInMessageId++;
         UWPInMessages[UWPInMessageId] = msg;
     }
-    else TRACELOG(LOG_WARNING, "[UWP Messaging] Not enough array space to register new UWP inbound Message.");
+    else TRACELOG(LOG_WARNING, "UWP: Not enough array space to register new inbound message");
 }
 
 void SendMessageToUWP(UWPMessage *msg)
@@ -388,7 +402,7 @@ void SendMessageToUWP(UWPMessage *msg)
         UWPOutMessageId++;
         UWPOutMessages[UWPOutMessageId] = msg;
     }
-    else TRACELOG(LOG_WARNING, "[UWP Messaging] Not enough array space to register new UWP outward Message.");
+    else TRACELOG(LOG_WARNING, "UWP: Not enough array space to register new outward message");
 }
 
 bool HasMessageFromUWP(void)

+ 2 - 2
lib.mod/raylib/src/utils.h

@@ -68,8 +68,8 @@ extern "C" {            // Prevents name mangling of functions
 // Module Functions Declaration
 //----------------------------------------------------------------------------------
 #if defined(PLATFORM_ANDROID)
-void InitAssetManager(AAssetManager *manager);  // Initialize asset manager from android app
-FILE *android_fopen(const char *fileName, const char *mode);    // Replacement for fopen()
+void InitAssetManager(AAssetManager *manager, const char *dataPath);   // Initialize asset manager from android app
+FILE *android_fopen(const char *fileName, const char *mode);            // Replacement for fopen() -> Read-only!
 #endif
 
 #if defined(PLATFORM_UWP)

+ 9 - 8
lib.mod/raylib/templates/advance_game/Makefile.Android

@@ -26,6 +26,8 @@ PLATFORM               ?= PLATFORM_ANDROID
 RAYLIB_PATH            ?= ..\..
 
 # Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
+# Starting in 2019 using ARM64 is mandatory for published apps,
+# and minimum required target API is Android 9 (API level 28)
 ANDROID_ARCH           ?= ARM
 ANDROID_API_VERSION     = 21
 ifeq ($(ANDROID_ARCH),ARM)
@@ -36,11 +38,11 @@ ifeq ($(ANDROID_ARCH),ARM64)
 endif
 
 # Required path variables
-# NOTE: JAVA_HOME must be set to JDK
-JAVA_HOME              ?= C:/JavaJDK
+# NOTE: JAVA_HOME must be set to JDK (using OpenJDK 13)
+JAVA_HOME              ?= C:/open-jdk
 ANDROID_HOME            = C:/android-sdk
-ANDROID_TOOLCHAIN       = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
-ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/28.0.1
+ANDROID_TOOLCHAIN       = C:/android-ndk-r21/toolchains/llvm/prebuilt/windows-x86_64
+ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/29.0.3
 ANDROID_PLATFORM_TOOLS  = $(ANDROID_HOME)/platform-tools
 
 # Android project configuration variables
@@ -81,13 +83,12 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
 endif
 
 # Compiler and archiver
-# NOTE: GCC is being deprecated in Android NDK r16
 ifeq ($(ANDROID_ARCH),ARM)
-    CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
 endif
 ifeq ($(ANDROID_ARCH),ARM64)
-    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
 endif
 
@@ -274,7 +275,7 @@ zipalign_project_apk_package:
 # Install $(PROJECT_NAME).apk to default emulator/device
 # NOTE: Use -e (emulator) or -d (device) parameters if required
 install:
-	$(ANDROID_PLATFORM_TOOLS)/adb install --abi $(ANDROID_ARCH_NAME) -rds $(PROJECT_NAME).apk
+	$(ANDROID_PLATFORM_TOOLS)/adb install $(PROJECT_NAME).apk
     
 # Check supported ABI for the device (armeabi-v7a, arm64-v8a, x86, x86_64)
 check_device_abi:

+ 10 - 9
lib.mod/raylib/templates/simple_game/Makefile.Android

@@ -26,8 +26,10 @@ PLATFORM               ?= PLATFORM_ANDROID
 RAYLIB_PATH            ?= ..\..
 
 # Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
+# Starting in 2019 using ARM64 is mandatory for published apps,
+# and minimum required target API is Android 9 (API level 28)
 ANDROID_ARCH           ?= ARM
-ANDROID_API_VERSION     = 21
+ANDROID_API_VERSION     = 28
 ifeq ($(ANDROID_ARCH),ARM)
     ANDROID_ARCH_NAME   = armeabi-v7a
 endif
@@ -36,11 +38,11 @@ ifeq ($(ANDROID_ARCH),ARM64)
 endif
 
 # Required path variables
-# NOTE: JAVA_HOME must be set to JDK
-JAVA_HOME              ?= C:/JavaJDK
+# NOTE: JAVA_HOME must be set to JDK (using OpenJDK 13)
+JAVA_HOME              ?= C:/open-jdk
 ANDROID_HOME            = C:/android-sdk
-ANDROID_TOOLCHAIN       = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
-ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/28.0.1
+ANDROID_TOOLCHAIN       = C:/android-ndk-r21/toolchains/llvm/prebuilt/windows-x86_64
+ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/29.0.3
 ANDROID_PLATFORM_TOOLS  = $(ANDROID_HOME)/platform-tools
 
 # Android project configuration variables
@@ -81,13 +83,12 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
 endif
 
 # Compiler and archiver
-# NOTE: GCC is being deprecated in Android NDK r16
 ifeq ($(ANDROID_ARCH),ARM)
-    CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
 endif
 ifeq ($(ANDROID_ARCH),ARM64)
-    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
 endif
 
@@ -274,7 +275,7 @@ zipalign_project_apk_package:
 # Install $(PROJECT_NAME).apk to default emulator/device
 # NOTE: Use -e (emulator) or -d (device) parameters if required
 install:
-	$(ANDROID_PLATFORM_TOOLS)/adb install --abi $(ANDROID_ARCH_NAME) -rds $(PROJECT_NAME).apk
+	$(ANDROID_PLATFORM_TOOLS)/adb install $(PROJECT_NAME).apk
     
 # Check supported ABI for the device (armeabi-v7a, arm64-v8a, x86, x86_64)
 check_device_abi:

+ 10 - 9
lib.mod/raylib/templates/standard_game/Makefile.Android

@@ -26,8 +26,10 @@ PLATFORM               ?= PLATFORM_ANDROID
 RAYLIB_PATH            ?= ..\..
 
 # Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
+# Starting in 2019 using ARM64 is mandatory for published apps,
+# and minimum required target API is Android 9 (API level 28)
 ANDROID_ARCH           ?= ARM
-ANDROID_API_VERSION     = 21
+ANDROID_API_VERSION     = 28
 ifeq ($(ANDROID_ARCH),ARM)
     ANDROID_ARCH_NAME   = armeabi-v7a
 endif
@@ -36,11 +38,11 @@ ifeq ($(ANDROID_ARCH),ARM64)
 endif
 
 # Required path variables
-# NOTE: JAVA_HOME must be set to JDK
-JAVA_HOME              ?= C:/JavaJDK
+# NOTE: JAVA_HOME must be set to JDK (using OpenJDK 13)
+JAVA_HOME              ?= C:/open-jdk
 ANDROID_HOME            = C:/android-sdk
-ANDROID_TOOLCHAIN       = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
-ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/28.0.1
+ANDROID_TOOLCHAIN       = C:/android-ndk-r21/toolchains/llvm/prebuilt/windows-x86_64
+ANDROID_BUILD_TOOLS     = $(ANDROID_HOME)/build-tools/29.0.3
 ANDROID_PLATFORM_TOOLS  = $(ANDROID_HOME)/platform-tools
 
 # Android project configuration variables
@@ -81,13 +83,12 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
 endif
 
 # Compiler and archiver
-# NOTE: GCC is being deprecated in Android NDK r16
 ifeq ($(ANDROID_ARCH),ARM)
-    CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
 endif
 ifeq ($(ANDROID_ARCH),ARM64)
-    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
+    CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
     AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
 endif
 
@@ -274,7 +275,7 @@ zipalign_project_apk_package:
 # Install $(PROJECT_NAME).apk to default emulator/device
 # NOTE: Use -e (emulator) or -d (device) parameters if required
 install:
-	$(ANDROID_PLATFORM_TOOLS)/adb install --abi $(ANDROID_ARCH_NAME) -rds $(PROJECT_NAME).apk
+	$(ANDROID_PLATFORM_TOOLS)/adb install $(PROJECT_NAME).apk
     
 # Check supported ABI for the device (armeabi-v7a, arm64-v8a, x86, x86_64)
 check_device_abi:

Some files were not shown because too many files changed in this diff