Browse Source

Update to version 1.0.3

View CHANGELOG for full list of changes
raysan5 11 years ago
parent
commit
5bf9675d38
40 changed files with 470 additions and 147 deletions
  1. 16 1
      CHANGELOG
  2. 10 1
      LICENSE.md
  3. 29 10
      examples/ex05a_sprite_fonts.c
  4. BIN
      examples/ex05a_sprite_fonts.exe
  5. BIN
      examples/ex05a_sprite_fonts.png
  6. 30 12
      examples/ex05b_rbmf_fonts.c
  7. BIN
      examples/ex05b_rbmf_fonts.exe
  8. BIN
      examples/ex05b_rbmf_fonts.png
  9. 1 1
      examples/ex08_audio.c
  10. 0 0
      examples/resources/audio/coin.wav
  11. 0 0
      examples/resources/audio/spring.wav
  12. 0 0
      examples/resources/audio/weird.wav
  13. BIN
      examples/resources/fonts/alagard.rbmf
  14. BIN
      examples/resources/fonts/alpha_beta.rbmf
  15. BIN
      examples/resources/fonts/custom_alagard.png
  16. BIN
      examples/resources/fonts/custom_jupiter_crash.png
  17. BIN
      examples/resources/fonts/custom_mecha.png
  18. BIN
      examples/resources/fonts/jupiter_crash.rbmf
  19. BIN
      examples/resources/fonts/mecha.rbmf
  20. BIN
      examples/resources/fonts/pixantiqua.rbmf
  21. BIN
      examples/resources/fonts/pixelplay.rbmf
  22. BIN
      examples/resources/fonts/romulus.rbmf
  23. BIN
      examples/resources/fonts/setback.rbmf
  24. BIN
      examples/resources/mouse.png
  25. BIN
      fonts/alagard.rbmf
  26. BIN
      fonts/alpha_beta.rbmf
  27. 0 0
      fonts/coming_soon
  28. BIN
      fonts/jupiter_crash.rbmf
  29. BIN
      fonts/mecha.rbmf
  30. BIN
      fonts/pixantiqua.rbmf
  31. BIN
      fonts/pixelplay.rbmf
  32. BIN
      fonts/romulus.rbmf
  33. BIN
      fonts/setback.rbmf
  34. 11 4
      release/win32-mingw/include/raylib.h
  35. BIN
      release/win32-mingw/lib/libraylib.a
  36. 67 8
      src/core.c
  37. 2 6
      src/models.c
  38. 11 4
      src/raylib.h
  39. 60 15
      src/shapes.c
  40. 233 85
      src/text.c

+ 16 - 1
CHANGELOG

@@ -1,11 +1,26 @@
 changelog
 changelog
 ---------
 ---------
 
 
-Current Release:    raylib 1.0.2 (December 2013)
+Current Release:    raylib 1.0.3 (December 2013)
 
 
 NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
 NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
 NOTE: Current Release includes all previous updates.
 NOTE: Current Release includes all previous updates.
 
 
+-----------------------------------------------
+Release:     raylib 1.0.3 (19 December 2013)
+-----------------------------------------------
+[fonts] Added 8 rBMF free fonts to be used on projects!
+[text] LoadSpriteFont() - Now supports rBMF file loading (raylib Bitmap Font)
+[examples] ex05a_sprite_fonts completed
+[examples] ex05b_rbmf_fonts completed
+[core] InitWindowEx() - InitWindow with extended parameters, resizing option and custom cursor!
+[core] GetRandomValue() - Added, returns a random value within a range (int)
+[core] SetExitKey() - Added, sets a key to exit program (default is ESC)
+[core] Custom cursor not drawn when mouse out of screen
+[shapes] CheckCollisionPointRec() - Added, check collision between point and rectangle
+[shapes] CheckCollisionPointCircle() - Added, check collision between point and circle
+[shapes] CheckCollisionPointTriangle() - Added, check collision between point and triangle
+[shapes] DrawPoly() - Added, draw regular polygons of n sides, rotation can be defined!
 
 
 -----------------------------------------------
 -----------------------------------------------
 Release:     raylib 1.0.2 (1 December 2013)
 Release:     raylib 1.0.2 (1 December 2013)

+ 10 - 1
LICENSE.md

@@ -27,4 +27,13 @@ applications, and to alter it and redistribute it freely, subject to the followi
 fonts
 fonts
 ------
 ------
 
 
-...soon...
+All rBMF fonts provided with raylib are free to use (freeware) and have been designed by the following people:
+
+Alpha Beta - Brian Kent (AEnigma)
+Setback - Brian Kent (AEnigma)
+Jupiter Crash - Brian Kent (AEnigma)
+Alagard - Hewett Tsoi
+Romulus - Hewett Tsoi
+Mecha - Captain Falcon
+PixelPlay - Aleksander Shevchuk
+PixAntiqua - Gerhard Großmann

+ 29 - 10
examples/ex05a_sprite_fonts.c

@@ -17,11 +17,29 @@ int main()
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
     int screenWidth = 800;
     int screenWidth = 800;
     int screenHeight = 450;
     int screenHeight = 450;
-
+    
+    const char msg1[50] = "THIS IS A custom SPRITE FONT...";
+    const char msg2[50] = "...and this is ANOTHER CUSTOM font...";
+    const char msg3[50] = "...and a THIRD one! GREAT! :D";
+    
     InitWindow(screenWidth, screenHeight, "raylib example 05a - sprite fonts");
     InitWindow(screenWidth, screenHeight, "raylib example 05a - sprite fonts");
     
     
-    // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
-    SpriteFont font = LoadSpriteFont("resources/custom_font.png");        // SpriteFont loading
+    // NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
+    SpriteFont font1 = LoadSpriteFont("resources/fonts/custom_mecha.png");          // SpriteFont loading
+    SpriteFont font2 = LoadSpriteFont("resources/fonts/custom_alagard.png");        // SpriteFont loading
+    SpriteFont font3 = LoadSpriteFont("resources/fonts/custom_jupiter_crash.png");  // SpriteFont loading
+    
+    Vector2 fontPosition1, fontPosition2, fontPosition3;
+    
+    fontPosition1.x = screenWidth/2 - MeasureTextEx(font1, msg1, GetFontBaseSize(font1), -3).x/2;
+    fontPosition1.y = screenHeight/2 - GetFontBaseSize(font1)/2 - 80;
+    
+    fontPosition2.x = screenWidth/2 - MeasureTextEx(font2, msg2, GetFontBaseSize(font2), -2).x/2;
+    fontPosition2.y = screenHeight/2 - GetFontBaseSize(font2)/2 - 10;
+    
+    fontPosition3.x = screenWidth/2 - MeasureTextEx(font3, msg3, GetFontBaseSize(font3), 2).x/2;
+    fontPosition3.y = screenHeight/2 - GetFontBaseSize(font3)/2 + 50;
+    
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
     
     
     // Main game loop
     // Main game loop
@@ -29,7 +47,7 @@ int main()
     {
     {
         // Update
         // Update
         //----------------------------------------------------------------------------------
         //----------------------------------------------------------------------------------
-        // TODO: Update your variables here
+        // TODO: Update variables here...
         //----------------------------------------------------------------------------------
         //----------------------------------------------------------------------------------
         
         
         // Draw
         // Draw
@@ -38,18 +56,19 @@ int main()
         
         
             ClearBackground(RAYWHITE);
             ClearBackground(RAYWHITE);
             
             
-            // TODO: Comming soon...
-            // TIP: Use DrawTextEx() function
-/*
-void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint);        
-*/        
+            DrawTextEx(font1, msg1, fontPosition1, GetFontBaseSize(font1), -3, WHITE);
+            DrawTextEx(font2, msg2, fontPosition2, GetFontBaseSize(font2), -2, WHITE);     
+            DrawTextEx(font3, msg3, fontPosition3, GetFontBaseSize(font3), 2, WHITE);                 
+      
         EndDrawing();
         EndDrawing();
         //----------------------------------------------------------------------------------
         //----------------------------------------------------------------------------------
     }
     }
 
 
     // De-Initialization
     // De-Initialization
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
-    UnloadSpriteFont(font);       // SpriteFont unloading
+    UnloadSpriteFont(font1);      // SpriteFont unloading
+    UnloadSpriteFont(font2);      // SpriteFont unloading
+    UnloadSpriteFont(font3);      // SpriteFont unloading
     
     
     CloseWindow();                // Close window and OpenGL context
     CloseWindow();                // Close window and OpenGL context
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------

BIN
examples/ex05a_sprite_fonts.exe


BIN
examples/ex05a_sprite_fonts.png


+ 30 - 12
examples/ex05b_rbmf_fonts.c

@@ -9,19 +9,26 @@
 *
 *
 ********************************************************************************************/
 ********************************************************************************************/
 
 
-#include "raylib.h"
+#include "../raylib.h"
 
 
 int main()
 int main()
 {
 {
     // Initialization
     // Initialization
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
-    int screenWidth = 800;
-    int screenHeight = 450;
+    int screenWidth = 560;
+    int screenHeight = 800;
 
 
-    InitWindow(screenWidth, screenHeight, "raylib example 04b - texture rectangle");
+    InitWindow(screenWidth, screenHeight, "raylib example 05b - rBMF fonts");
     
     
     // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
     // NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
-    SpriteFont font = LoadSpriteFont("resources/custom_font.rbmf");        // SpriteFont loading
+    SpriteFont font1 = LoadSpriteFont("resources/fonts/alagard.rbmf");       // SpriteFont loading
+    SpriteFont font2 = LoadSpriteFont("resources/fonts/pixelplay.rbmf");     // SpriteFont loading
+    SpriteFont font3 = LoadSpriteFont("resources/fonts/mecha.rbmf");         // SpriteFont loading
+    SpriteFont font4 = LoadSpriteFont("resources/fonts/setback.rbmf");       // SpriteFont loading
+    SpriteFont font5 = LoadSpriteFont("resources/fonts/romulus.rbmf");       // SpriteFont loading
+    SpriteFont font6 = LoadSpriteFont("resources/fonts/pixantiqua.rbmf");    // SpriteFont loading
+    SpriteFont font7 = LoadSpriteFont("resources/fonts/alpha_beta.rbmf");    // SpriteFont loading
+    SpriteFont font8 = LoadSpriteFont("resources/fonts/jupiter_crash.rbmf"); // SpriteFont loading
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
     
     
     // Main game loop
     // Main game loop
@@ -38,20 +45,31 @@ int main()
         
         
             ClearBackground(RAYWHITE);
             ClearBackground(RAYWHITE);
             
             
-            // TODO: Comming soon...
-            // TIP: Use DrawTextEx() function
-/*
-void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint);        
-*/         
+            DrawTextEx(font1, "TESTING ALAGARD FONT", (Vector2){ 100, 100 }, GetFontBaseSize(font1)*2, 2, MAROON);
+            DrawTextEx(font2, "TESTING PIXELPLAY FONT", (Vector2){ 100, 180 }, GetFontBaseSize(font2)*2, 4, ORANGE);  
+            DrawTextEx(font3, "TESTING MECHA FONT", (Vector2){ 100, 260 }, GetFontBaseSize(font3)*2, 8, DARKGREEN);  
+            DrawTextEx(font4, "TESTING SETBACK FONT", (Vector2){ 100, 350 }, GetFontBaseSize(font4)*2, 4, DARKBLUE);  
+            DrawTextEx(font5, "TESTING ROMULUS FONT", (Vector2){ 100, 430 }, GetFontBaseSize(font5)*2, 3, DARKPURPLE);
+            DrawTextEx(font6, "TESTING PIXANTIQUA FONT", (Vector2){ 100, 510 }, GetFontBaseSize(font6)*2, 4, LIME);  
+            DrawTextEx(font7, "TESTING ALPHA_BETA FONT", (Vector2){ 100, 590 }, GetFontBaseSize(font7)*2, 4, GOLD);  
+            DrawTextEx(font8, "TESTING JUPITER_CRASH FONT", (Vector2){ 100, 660 }, GetFontBaseSize(font8)*2, 1, RED);               
+       
         EndDrawing();
         EndDrawing();
         //----------------------------------------------------------------------------------
         //----------------------------------------------------------------------------------
     }
     }
 
 
     // De-Initialization
     // De-Initialization
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
-    UnloadSpriteFont(font);       // SpriteFont unloading
+    UnloadSpriteFont(font1);       // SpriteFont unloading
+    UnloadSpriteFont(font2);       // SpriteFont unloading
+    UnloadSpriteFont(font3);       // SpriteFont unloading
+    UnloadSpriteFont(font4);       // SpriteFont unloading
+    UnloadSpriteFont(font5);       // SpriteFont unloading
+    UnloadSpriteFont(font6);       // SpriteFont unloading
+    UnloadSpriteFont(font7);       // SpriteFont unloading
+    UnloadSpriteFont(font8);       // SpriteFont unloading
     
     
-    CloseWindow();                // Close window and OpenGL context
+    CloseWindow();                 // Close window and OpenGL context
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
     
     
     return 0;
     return 0;

BIN
examples/ex05b_rbmf_fonts.exe


BIN
examples/ex05b_rbmf_fonts.png


+ 1 - 1
examples/ex08_audio.c

@@ -24,7 +24,7 @@ int main()
     
     
     InitAudioDevice();      // Initialize audio device
     InitAudioDevice();      // Initialize audio device
     
     
-    Sound fx = LoadSound("resources/weird.wav");         // Load WAV audio file
+    Sound fx = LoadSound("resources/audio/weird.wav");         // Load WAV audio file
     //--------------------------------------------------------------------------------------
     //--------------------------------------------------------------------------------------
     
     
     // Main game loop
     // Main game loop

+ 0 - 0
examples/resources/coin.wav → examples/resources/audio/coin.wav


+ 0 - 0
examples/resources/spring.wav → examples/resources/audio/spring.wav


+ 0 - 0
examples/resources/weird.wav → examples/resources/audio/weird.wav


BIN
examples/resources/fonts/alagard.rbmf


BIN
examples/resources/fonts/alpha_beta.rbmf


BIN
examples/resources/fonts/custom_alagard.png


BIN
examples/resources/fonts/custom_jupiter_crash.png


BIN
examples/resources/fonts/custom_mecha.png


BIN
examples/resources/fonts/jupiter_crash.rbmf


BIN
examples/resources/fonts/mecha.rbmf


BIN
examples/resources/fonts/pixantiqua.rbmf


BIN
examples/resources/fonts/pixelplay.rbmf


BIN
examples/resources/fonts/romulus.rbmf


BIN
examples/resources/fonts/setback.rbmf


BIN
examples/resources/mouse.png


BIN
fonts/alagard.rbmf


BIN
fonts/alpha_beta.rbmf


+ 0 - 0
fonts/coming_soon


BIN
fonts/jupiter_crash.rbmf


BIN
fonts/mecha.rbmf


BIN
fonts/pixantiqua.rbmf


BIN
fonts/pixelplay.rbmf


BIN
fonts/romulus.rbmf


BIN
fonts/setback.rbmf


+ 11 - 4
release/win32-mingw/include/raylib.h

@@ -1,6 +1,6 @@
 /*********************************************************************************************
 /*********************************************************************************************
 * 
 * 
-*   raylib 1.0.2 (www.raylib.com)
+*   raylib 1.0.3 (www.raylib.com)
 *    
 *    
 *   A simple and easy-to-use library to learn C videogames programming
 *   A simple and easy-to-use library to learn C videogames programming
 *
 *
@@ -236,10 +236,13 @@ extern "C" {            // Prevents name mangling of functions
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Window and Graphics Device Functions (Module: core)
 // Window and Graphics Device Functions (Module: core)
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
-void InitWindow(int width, int height, char* title);    // Initialize Window and Graphics Context (OpenGL)
+void InitWindow(int width, int height, const char *title);    // Initialize Window and Graphics Context (OpenGL)
+void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage);
 void CloseWindow();                                     // Close Window and Terminate Context
 void CloseWindow();                                     // Close Window and Terminate Context
 bool WindowShouldClose();                               // Detect if KEY_ESCAPE pressed or Close icon pressed
 bool WindowShouldClose();                               // Detect if KEY_ESCAPE pressed or Close icon pressed
 void ToggleFullscreen();                                // Fullscreen toggle (by default F11)
 void ToggleFullscreen();                                // Fullscreen toggle (by default F11)
+void SetCustomCursor(const char *cursorImage);          // Set a custom cursor icon/image
+void SetExitKey(int key);                               // Set a custom key to exit program (default is ESC)
 
 
 void ClearBackground(Color color);                      // Sets Background Color
 void ClearBackground(Color color);                      // Sets Background Color
 void BeginDrawing();                                    // Setup drawing canvas to start drawing
 void BeginDrawing();                                    // Setup drawing canvas to start drawing
@@ -255,6 +258,8 @@ float GetFrameTime();                                   // Returns time in secon
 Color GetColor(int hexValue);                           // Returns a Color struct from hexadecimal value
 Color GetColor(int hexValue);                           // Returns a Color struct from hexadecimal value
 int GetHexValue(Color color);                           // Returns hexadecimal value for a Color
 int GetHexValue(Color color);                           // Returns hexadecimal value for a Color
 
 
+int GetRandomValue(int min, int max);                   // Returns a random value between min and max (both included)
+
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Input Handling Functions (Module: core)
 // Input Handling Functions (Module: core)
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
@@ -296,8 +301,9 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color);
 void DrawRectangleLines(int posX, int posY, int width, int height, Color color);                   // Draw rectangle outline
 void DrawRectangleLines(int posX, int posY, int width, int height, Color color);                   // Draw rectangle outline
 void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                                // Draw a color-filled triangle
 void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                                // Draw a color-filled triangle
 void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                           // Draw triangle outline
 void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                           // Draw triangle outline
-void DrawPoly(Vector2 *points, int numPoints, Color color);                                        // Draw a closed polygon defined by points
-void DrawPolyLine(Vector2 *points, int numPoints, Color color);                                    // Draw polygon lines
+void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color);               // Draw a regular polygon (Vector version)
+void DrawPolyEx(Vector2 *points, int numPoints, Color color);                                      // Draw a closed polygon defined by points
+void DrawPolyExLines(Vector2 *points, int numPoints, Color color);                                 // Draw polygon lines
 
 
 bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2);                                           // Check collision between two rectangles
 bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2);                                           // Check collision between two rectangles
 bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2);        // Check collision between two circles
 bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2);        // Check collision between two circles
@@ -323,6 +329,7 @@ Texture2D CreateTexture2D(Image image);
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 SpriteFont GetDefaultFont();                                                                       // Get the default SpriteFont
 SpriteFont GetDefaultFont();                                                                       // Get the default SpriteFont
 SpriteFont LoadSpriteFont(const char *fileName);                                                   // Load a SpriteFont image into GPU memory
 SpriteFont LoadSpriteFont(const char *fileName);                                                   // Load a SpriteFont image into GPU memory
+SpriteFont LoadFontRBMF(const char *fileName);
 void UnloadSpriteFont(SpriteFont spriteFont);                                                      // Unload SpriteFont from GPU memory
 void UnloadSpriteFont(SpriteFont spriteFont);                                                      // Unload SpriteFont from GPU memory
 void DrawText(const char *text, int posX, int posY, int fontSize, Color color);                    // Draw text (using default font)
 void DrawText(const char *text, int posX, int posY, int fontSize, Color color);                    // Draw text (using default font)
 void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont
 void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont

BIN
release/win32-mingw/lib/libraylib.a


+ 67 - 8
src/core.c

@@ -31,7 +31,8 @@
 #include <GLFW/glfw3.h>     // GLFW3 lib: Windows, OpenGL context and Input management
 #include <GLFW/glfw3.h>     // GLFW3 lib: Windows, OpenGL context and Input management
 //#include <GL/gl.h>        // OpenGL functions (GLFW3 already includes gl.h)
 //#include <GL/gl.h>        // OpenGL functions (GLFW3 already includes gl.h)
 #include <stdio.h>          // Standard input / output lib
 #include <stdio.h>          // Standard input / output lib
-#include <stdlib.h>         // Declares malloc() and free() for memory management
+#include <stdlib.h>         // Declares malloc() and free() for memory management, rand()
+#include <time.h>           // Useful to initialize random seed
 #include <math.h>           // Math related functions, tan() on SetPerspective
 #include <math.h>           // Math related functions, tan() on SetPerspective
 #include "vector3.h"        // Basic Vector3 functions
 #include "vector3.h"        // Basic Vector3 functions
 
 
@@ -59,7 +60,12 @@ static double frameTime;                    // Time measure for one frame
 static double targetTime = 0;               // Desired time for one frame, if 0 not applied
 static double targetTime = 0;               // Desired time for one frame, if 0 not applied
 
 
 static int windowWidth, windowHeight;       // Required to switch between windowed/fullscren mode (F11)
 static int windowWidth, windowHeight;       // Required to switch between windowed/fullscren mode (F11)
-static char *windowTitle;                   // Required to switch between windowed/fullscren mode (F11)
+static const char *windowTitle;             // Required to switch between windowed/fullscren mode (F11)
+static int exitKey = GLFW_KEY_ESCAPE;
+
+static bool customCursor = false;           // Tracks if custom cursor has been set
+static bool cursorOnScreen = false;         // Tracks if cursor is inside client area
+static Texture2D cursor;                    // Cursor texture
 
 
 static char previousKeyState[512] = { 0 };  // Required to check if key pressed/released once
 static char previousKeyState[512] = { 0 };  // Required to check if key pressed/released once
 static char currentKeyState[512] = { 0 };   // Required to check if key pressed/released once
 static char currentKeyState[512] = { 0 };   // Required to check if key pressed/released once
@@ -83,6 +89,7 @@ extern void WriteBitmap(const char *fileName, const pixel *imgDataPixel, int wid
 static void InitGraphicsDevice();                                                          // Initialize Graphics Device (OpenGL stuff)
 static void InitGraphicsDevice();                                                          // Initialize Graphics Device (OpenGL stuff)
 static void ErrorCallback(int error, const char *description);                             // GLFW3 Error Callback, runs on GLFW3 error
 static void ErrorCallback(int error, const char *description);                             // GLFW3 Error Callback, runs on GLFW3 error
 static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);  // GLFW3 Keyboard Callback, runs on key pressed
 static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);  // GLFW3 Keyboard Callback, runs on key pressed
+static void CursorEnterCallback(GLFWwindow* window, int enter);                            // GLFW3 Cursor Enter Callback, cursor enters client area
 static void WindowSizeCallback(GLFWwindow* window, int width, int height);                 // GLFW3 WindowSize Callback, runs when window is resized
 static void WindowSizeCallback(GLFWwindow* window, int width, int height);                 // GLFW3 WindowSize Callback, runs when window is resized
 static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up);                    // Setup camera view (updates MODELVIEW matrix)
 static void CameraLookAt(Vector3 position, Vector3 target, Vector3 up);                    // Setup camera view (updates MODELVIEW matrix)
 static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); // Setup view projection (updates PROJECTION matrix)
 static void SetPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); // Setup view projection (updates PROJECTION matrix)
@@ -93,13 +100,21 @@ static void TakeScreenshot();
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 
 
 // Initialize Window and Graphics Context (OpenGL)
 // Initialize Window and Graphics Context (OpenGL)
-void InitWindow(int width, int height, char* title)
+void InitWindow(int width, int height, const char *title)
+{
+    InitWindowEx(width, height, title, true, NULL);
+}
+
+// Initialize Window and Graphics Context (OpenGL) with extended parameters
+void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage)
 {
 {
     glfwSetErrorCallback(ErrorCallback);
     glfwSetErrorCallback(ErrorCallback);
     
     
     if (!glfwInit()) exit(1);
     if (!glfwInit()) exit(1);
     
     
-    //glfwWindowHint(GLFW_SAMPLES, 4);    // If called before windows creation, enables multisampling x4 (MSAA), default is 0
+    //glfwDefaultWindowHints()                  // Set default windows hints
+    //glfwWindowHint(GLFW_SAMPLES, 4);          // If called before windows creation, enables multisampling x4 (MSAA), default is 0
+    if (!resizable) glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
         
         
     window = glfwCreateWindow(width, height, title, NULL, NULL);
     window = glfwCreateWindow(width, height, title, NULL, NULL);
     
     
@@ -114,6 +129,7 @@ void InitWindow(int width, int height, char* title)
     }
     }
     
     
     glfwSetWindowSizeCallback(window, WindowSizeCallback);
     glfwSetWindowSizeCallback(window, WindowSizeCallback);
+    glfwSetCursorEnterCallback(window, CursorEnterCallback);
     
     
     glfwMakeContextCurrent(window);
     glfwMakeContextCurrent(window);
     glfwSetKeyCallback(window, KeyCallback);
     glfwSetKeyCallback(window, KeyCallback);
@@ -125,6 +141,17 @@ void InitWindow(int width, int height, char* title)
     previousTime = glfwGetTime();
     previousTime = glfwGetTime();
 
 
     LoadDefaultFont();
     LoadDefaultFont();
+    
+    if (cursorImage != NULL) 
+    {
+        // Load image as texture
+        cursor = LoadTexture(cursorImage);  
+    
+        glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+        customCursor = true;
+    }
+    
+    srand(time(NULL));      // Initialize random seed
 }
 }
 
 
 // Close Window and Terminate Context
 // Close Window and Terminate Context
@@ -136,6 +163,24 @@ void CloseWindow()
     glfwTerminate();
     glfwTerminate();
 }
 }
 
 
+// Set a custom cursor icon/image
+void SetCustomCursor(const char *cursorImage)
+{
+    if (customCursor) UnloadTexture(cursor);
+    
+    cursor = LoadTexture(cursorImage);
+    
+    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
+    customCursor = true;
+}
+
+// Set a custom key to exit program
+// NOTE: default exitKey is ESCAPE
+void SetExitKey(int key)
+{
+    exitKey = key;
+}
+
 // Detect if KEY_ESCAPE pressed or Close icon pressed
 // Detect if KEY_ESCAPE pressed or Close icon pressed
 bool WindowShouldClose()
 bool WindowShouldClose()
 {
 {
@@ -197,6 +242,8 @@ void BeginDrawing()
 // End canvas drawing and Swap Buffers (Double Buffering)
 // End canvas drawing and Swap Buffers (Double Buffering)
 void EndDrawing()
 void EndDrawing()
 {
 {
+    if (customCursor && cursorOnScreen) DrawTexture(cursor, GetMouseX(), GetMouseY(), WHITE);
+
     glfwSwapBuffers(window);            // Swap back and front buffers
     glfwSwapBuffers(window);            // Swap back and front buffers
     glfwPollEvents();                   // Register keyboard/mouse events
     glfwPollEvents();                   // Register keyboard/mouse events
     
     
@@ -294,6 +341,12 @@ int GetHexValue(Color color)
     return ((color.a << 24) + (color.r << 16) + (color.g << 8) + color.b);
     return ((color.a << 24) + (color.r << 16) + (color.g << 8) + color.b);
 }
 }
 
 
+// Returns a random value between min and max (both included)
+int GetRandomValue(int min, int max)
+{
+    return (rand()%(abs(max-min)+1) - abs(min));
+}
+
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
 // Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
@@ -529,14 +582,14 @@ bool IsGamepadButtonUp(int gamepad, int button)
 // GLFW3 Error Callback, runs on GLFW3 error
 // GLFW3 Error Callback, runs on GLFW3 error
 static void ErrorCallback(int error, const char *description)
 static void ErrorCallback(int error, const char *description)
 {
 {
-    //printf(description);
-    fprintf(stderr, "%s", description);
+    printf(description);
+    //fprintf(stderr, description);
 }
 }
 
 
 // GLFW3 Keyboard Callback, runs on key pressed
 // GLFW3 Keyboard Callback, runs on key pressed
 static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
 static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods)
 {
 {
-    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
+    if (key == exitKey && action == GLFW_PRESS)
     {
     {
         glfwSetWindowShouldClose(window, GL_TRUE);
         glfwSetWindowShouldClose(window, GL_TRUE);
         
         
@@ -552,6 +605,12 @@ static void KeyCallback(GLFWwindow* window, int key, int scancode, int action, i
     }
     }
 }
 }
 
 
+static void CursorEnterCallback(GLFWwindow* window, int enter)
+{
+    if (enter == GL_TRUE) cursorOnScreen = true;
+    else cursorOnScreen = false;
+}
+
 // GLFW3 WindowSize Callback, runs when window is resized
 // GLFW3 WindowSize Callback, runs when window is resized
 static void WindowSizeCallback(GLFWwindow* window, int width, int height)
 static void WindowSizeCallback(GLFWwindow* window, int width, int height)
 {
 {
@@ -688,4 +747,4 @@ static void TakeScreenshot()
     free(imgDataPixel);
     free(imgDataPixel);
     
     
     shotNum++;
     shotNum++;
-}
+}

+ 2 - 6
src/models.c

@@ -181,8 +181,6 @@ void DrawSphereWires(Vector3 centerPos, float radius, Color color)
 // Draw a cylinder/cone
 // Draw a cylinder/cone
 void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color)    // Could be used for pyramid and cone!
 void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color)    // Could be used for pyramid and cone!
 {
 {
-    static int count = 0;
-    
     Vector3 a = { position.x, position.y + height, position.z };
     Vector3 a = { position.x, position.y + height, position.z };
     Vector3 d = { 0.0f, 1.0f, 0.0f };
     Vector3 d = { 0.0f, 1.0f, 0.0f };
     Vector3 p;
     Vector3 p;
@@ -202,7 +200,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
         
         
         glPushMatrix();
         glPushMatrix();
             //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
             //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
-            glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
+            //glRotatef(degrees, 0.0f, 1.0f, 0.0f);
             //glScalef(1.0f, 1.0f, 1.0f);
             //glScalef(1.0f, 1.0f, 1.0f);
             
             
             // Draw cone top
             // Draw cone top
@@ -239,7 +237,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
     {
     {
         glPushMatrix();
         glPushMatrix();
             //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
             //glTranslatef(centerPos.x, centerPos.y, centerPos.z);
-            glRotatef(DEG2RAD*count, 0.0f, 1.0f, 0.0f);
+            //glRotatef(degrees, 0.0f, 1.0f, 0.0f);
             //glScalef(1.0f, 1.0f, 1.0f);
             //glScalef(1.0f, 1.0f, 1.0f);
 
 
             // Draw cylinder top (pointed cap)
             // Draw cylinder top (pointed cap)
@@ -290,8 +288,6 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
             
             
         glPopMatrix();
         glPopMatrix();
     }
     }
-    
-    count += 1;
 }
 }
 
 
 // Draw a cylinder/cone wires
 // Draw a cylinder/cone wires

+ 11 - 4
src/raylib.h

@@ -1,6 +1,6 @@
 /*********************************************************************************************
 /*********************************************************************************************
 * 
 * 
-*   raylib 1.0.2 (www.raylib.com)
+*   raylib 1.0.3 (www.raylib.com)
 *    
 *    
 *   A simple and easy-to-use library to learn C videogames programming
 *   A simple and easy-to-use library to learn C videogames programming
 *
 *
@@ -236,10 +236,13 @@ extern "C" {            // Prevents name mangling of functions
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Window and Graphics Device Functions (Module: core)
 // Window and Graphics Device Functions (Module: core)
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
-void InitWindow(int width, int height, char* title);    // Initialize Window and Graphics Context (OpenGL)
+void InitWindow(int width, int height, const char *title);    // Initialize Window and Graphics Context (OpenGL)
+void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage);
 void CloseWindow();                                     // Close Window and Terminate Context
 void CloseWindow();                                     // Close Window and Terminate Context
 bool WindowShouldClose();                               // Detect if KEY_ESCAPE pressed or Close icon pressed
 bool WindowShouldClose();                               // Detect if KEY_ESCAPE pressed or Close icon pressed
 void ToggleFullscreen();                                // Fullscreen toggle (by default F11)
 void ToggleFullscreen();                                // Fullscreen toggle (by default F11)
+void SetCustomCursor(const char *cursorImage);          // Set a custom cursor icon/image
+void SetExitKey(int key);                               // Set a custom key to exit program (default is ESC)
 
 
 void ClearBackground(Color color);                      // Sets Background Color
 void ClearBackground(Color color);                      // Sets Background Color
 void BeginDrawing();                                    // Setup drawing canvas to start drawing
 void BeginDrawing();                                    // Setup drawing canvas to start drawing
@@ -255,6 +258,8 @@ float GetFrameTime();                                   // Returns time in secon
 Color GetColor(int hexValue);                           // Returns a Color struct from hexadecimal value
 Color GetColor(int hexValue);                           // Returns a Color struct from hexadecimal value
 int GetHexValue(Color color);                           // Returns hexadecimal value for a Color
 int GetHexValue(Color color);                           // Returns hexadecimal value for a Color
 
 
+int GetRandomValue(int min, int max);                   // Returns a random value between min and max (both included)
+
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 // Input Handling Functions (Module: core)
 // Input Handling Functions (Module: core)
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
@@ -296,8 +301,9 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color);
 void DrawRectangleLines(int posX, int posY, int width, int height, Color color);                   // Draw rectangle outline
 void DrawRectangleLines(int posX, int posY, int width, int height, Color color);                   // Draw rectangle outline
 void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                                // Draw a color-filled triangle
 void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                                // Draw a color-filled triangle
 void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                           // Draw triangle outline
 void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color);                           // Draw triangle outline
-void DrawPoly(Vector2 *points, int numPoints, Color color);                                        // Draw a closed polygon defined by points
-void DrawPolyLine(Vector2 *points, int numPoints, Color color);                                    // Draw polygon lines
+void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color);               // Draw a regular polygon (Vector version)
+void DrawPolyEx(Vector2 *points, int numPoints, Color color);                                      // Draw a closed polygon defined by points
+void DrawPolyExLines(Vector2 *points, int numPoints, Color color);                                 // Draw polygon lines
 
 
 bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2);                                           // Check collision between two rectangles
 bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2);                                           // Check collision between two rectangles
 bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2);        // Check collision between two circles
 bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2);        // Check collision between two circles
@@ -323,6 +329,7 @@ Texture2D CreateTexture2D(Image image);
 //------------------------------------------------------------------------------------
 //------------------------------------------------------------------------------------
 SpriteFont GetDefaultFont();                                                                       // Get the default SpriteFont
 SpriteFont GetDefaultFont();                                                                       // Get the default SpriteFont
 SpriteFont LoadSpriteFont(const char *fileName);                                                   // Load a SpriteFont image into GPU memory
 SpriteFont LoadSpriteFont(const char *fileName);                                                   // Load a SpriteFont image into GPU memory
+SpriteFont LoadFontRBMF(const char *fileName);
 void UnloadSpriteFont(SpriteFont spriteFont);                                                      // Unload SpriteFont from GPU memory
 void UnloadSpriteFont(SpriteFont spriteFont);                                                      // Unload SpriteFont from GPU memory
 void DrawText(const char *text, int posX, int posY, int fontSize, Color color);                    // Draw text (using default font)
 void DrawText(const char *text, int posX, int posY, int fontSize, Color color);                    // Draw text (using default font)
 void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont
 void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont

+ 60 - 15
src/shapes.c

@@ -102,23 +102,13 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
 }
 }
 
 
 // Draw a color-filled circle
 // Draw a color-filled circle
+// TODO: Review, on some GPUs is drawn with a weird transparency (GL_POLYGON_SMOOTH issue?)
 void DrawCircle(int centerX, int centerY, float radius, Color color)
 void DrawCircle(int centerX, int centerY, float radius, Color color)
 {
 {
     glEnable(GL_POLYGON_SMOOTH);
     glEnable(GL_POLYGON_SMOOTH);
-    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);  // Deprecated on OGL 3.0
     
     
-    glBegin(GL_TRIANGLE_FAN);
-        glColor4ub(color.r, color.g, color.b, color.a);
-        glVertex2i(centerX, centerY);
-
-        for (int i=0; i <= 360; i++)        //i++ --> Step = 1.0 pixels
-        {
-            float degInRad = i*DEG2RAD;
-            //glVertex2f(cos(degInRad)*radius,sin(degInRad)*radius);
-
-            glVertex2f(centerX + sin(degInRad) * radius, centerY + cos(degInRad) * radius);
-        }
-    glEnd();
+    DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
     
     
     glDisable(GL_POLYGON_SMOOTH);
     glDisable(GL_POLYGON_SMOOTH);
     
     
@@ -283,9 +273,30 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
     glEnd();
     glEnd();
 }
 }
 
 
+// Draw a regular polygon of n sides (Vector version)
+void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color)
+{
+    if (sides < 3) sides = 3;
+
+    glPushMatrix();
+        glTranslatef(center.x, center.y, 0);
+        glRotatef(rotation, 0, 0, 1);
+        
+        glBegin(GL_TRIANGLE_FAN);
+            glColor4ub(color.r, color.g, color.b, color.a);
+            glVertex2f(0, 0);
+
+            for (int i=0; i <= sides; i++)
+            { 
+                glVertex2f(radius*cos(i*2*PI/sides), radius*sin(i*2*PI/sides));
+            }
+        glEnd();
+    glPopMatrix();
+}
+
 // Draw a closed polygon defined by points
 // Draw a closed polygon defined by points
 // NOTE: Array num elements MUST be passed as parameter to function
 // NOTE: Array num elements MUST be passed as parameter to function
-void DrawPoly(Vector2 *points, int numPoints, Color color)
+void DrawPolyEx(Vector2 *points, int numPoints, Color color)
 {
 {
     if (numPoints >= 3)
     if (numPoints >= 3)
     {
     {
@@ -307,7 +318,7 @@ void DrawPoly(Vector2 *points, int numPoints, Color color)
 
 
 // Draw polygon lines
 // Draw polygon lines
 // NOTE: Array num elements MUST be passed as parameter to function                                                
 // NOTE: Array num elements MUST be passed as parameter to function                                                
-void DrawPolyLine(Vector2 *points, int numPoints, Color color)
+void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
 {
 {
     if (numPoints >= 2)
     if (numPoints >= 2)
     {
     {
@@ -327,6 +338,40 @@ void DrawPolyLine(Vector2 *points, int numPoints, Color color)
     }
     }
 }
 }
 
 
+// Check if point is inside rectangle
+bool CheckCollisionPointRec(Vector2 point, Rectangle rec)
+{
+    bool collision = false;
+    
+    if ((point.x >= rec.x) && (point.x <= (rec.x + rec.width)) && (point.y >= rec.y) && (point.y <= (rec.y + rec.height))) collision = true;
+    
+    return collision;
+}
+
+// Check if point is inside circle
+bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius)
+{
+    return CheckCollisionCircles(point, 0, center, radius);
+}
+
+// Check if point is inside a triangle defined by three points (p1, p2, p3)
+bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3)
+{
+    bool collision = false;
+
+    float alpha = ((p2.y - p3.y)*(point.x - p3.x) + (p3.x - p2.x)*(point.y - p3.y)) /
+                  ((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
+                  
+    float beta = ((p3.y - p1.y)*(point.x - p3.x) + (p1.x - p3.x)*(point.y - p3.y)) /
+                 ((p2.y - p3.y)*(p1.x - p3.x) + (p3.x - p2.x)*(p1.y - p3.y));
+                 
+    float gamma = 1.0f - alpha - beta;
+
+    if ((alpha > 0) && (beta > 0) & (gamma > 0)) collision = true;
+    
+    return collision;
+}
+
 // Check collision between two rectangles
 // Check collision between two rectangles
 bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
 bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
 {
 {

+ 233 - 85
src/text.c

@@ -65,9 +65,11 @@ static SpriteFont defaultFont;        // Default font provided by raylib
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module specific Functions Declaration
 // Module specific Functions Declaration
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
-static bool PixelIsMagenta(Color p);        // Check if a pixel is magenta
+static bool PixelIsMagenta(Color p);                // Check if a pixel is magenta
 static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet);    // Parse image pixel data to obtain character set measures
 static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet);    // Parse image pixel data to obtain character set measures
-static int GetNextPOT(int num);             // Calculate next power-of-two value for a given value
+static int GetNextPOT(int num);                     // Calculate next power-of-two value for a given value
+static SpriteFont LoadRBMF(const char *fileName);   // Load a rBMF font file (raylib BitMap Font)
+static const char *GetExtension(const char *fileName);
 
 
 //----------------------------------------------------------------------------------
 //----------------------------------------------------------------------------------
 // Module Functions Definition
 // Module Functions Definition
@@ -203,80 +205,90 @@ SpriteFont LoadSpriteFont(const char* fileName)
 {
 {
     SpriteFont spriteFont;
     SpriteFont spriteFont;
     
     
-    // Use stb_image to load image data!
-    int imgWidth;
-    int imgHeight;
-    int imgBpp;
-    
-    byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);    // Force loading to 4 components (RGBA)
-    
-    // Convert array to pixel array for working convenience
-    Color *imgDataPixel = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
-    Color *imgDataPixelPOT = NULL;
-    
-    int pix = 0;
-    
-    for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
-    {
-        imgDataPixel[pix].r = imgData[i];
-        imgDataPixel[pix].g = imgData[i+1];
-        imgDataPixel[pix].b = imgData[i+2];
-        imgDataPixel[pix].a = imgData[i+3];
-        pix++;
-    }
-    
-    stbi_image_free(imgData);
-    
-    // At this point we have a pixel array with all the data...
-    
-    // Process bitmap Font pixel data to get measures (Character array)
-    // spriteFont.charSet data is filled inside the function and memory is allocated!
-    int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
-    
-    spriteFont.numChars = numChars;
-    
-    // Convert image font to POT image before conversion to texture
-    // Just add the required amount of pixels at the right and bottom sides of image...
-    int potWidth = GetNextPOT(imgWidth);
-    int potHeight = GetNextPOT(imgHeight);
-    
-    // Check if POT texture generation is required (if texture is not already POT)
-    if ((potWidth != imgWidth) || (potHeight != imgWidth))
-    {
-        // Generate POT array from NPOT data
-        imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
+    // Check file extension
+    if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
+    else
+    {   
+        // Use stb_image to load image data!
+        int imgWidth;
+        int imgHeight;
+        int imgBpp;
         
         
-        for (int j = 0; j < potHeight; j++)
+        byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4);    // Force loading to 4 components (RGBA)
+        
+        // Convert array to pixel array for working convenience
+        Color *imgDataPixel = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
+        Color *imgDataPixelPOT = NULL;
+        
+        int pix = 0;
+        
+        for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
         {
         {
-            for (int i = 0; i < potWidth; i++)
+            imgDataPixel[pix].r = imgData[i];
+            imgDataPixel[pix].g = imgData[i+1];
+            imgDataPixel[pix].b = imgData[i+2];
+            imgDataPixel[pix].a = imgData[i+3];
+            pix++;
+        }
+        
+        stbi_image_free(imgData);
+        
+        // At this point we have a pixel array with all the data...
+        
+        // Process bitmap Font pixel data to get measures (Character array)
+        // spriteFont.charSet data is filled inside the function and memory is allocated!
+        int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
+        
+        fprintf(stderr, "SpriteFont data parsed correctly!\n");
+        fprintf(stderr, "SpriteFont num chars: %i\n", numChars);
+        
+        spriteFont.numChars = numChars;
+        
+        // Convert image font to POT image before conversion to texture
+        // Just add the required amount of pixels at the right and bottom sides of image...
+        int potWidth = GetNextPOT(imgWidth);
+        int potHeight = GetNextPOT(imgHeight);
+        
+        // Check if POT texture generation is required (if texture is not already POT)
+        if ((potWidth != imgWidth) || (potHeight != imgHeight))
+        {
+            // Generate POT array from NPOT data
+            imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
+            
+            for (int j = 0; j < potHeight; j++)
             {
             {
-                if ((j < imgHeight) && (i < imgWidth)) imgDataPixelPOT[j*potWidth + i] = imgDataPixel[j*imgWidth + i];
-                else imgDataPixelPOT[j*potWidth + i] = MAGENTA;
+                for (int i = 0; i < potWidth; i++)
+                {
+                    if ((j < imgHeight) && (i < imgWidth)) imgDataPixelPOT[j*potWidth + i] = imgDataPixel[j*imgWidth + i];
+                    else imgDataPixelPOT[j*potWidth + i] = MAGENTA;
+                }
             }
             }
+            
+            fprintf(stderr, "SpriteFont texture converted to POT: %i %i\n", potWidth, potHeight);
         }
         }
-    }
-    
-    free(imgDataPixel);
+        
+        free(imgDataPixel);
 
 
-    // Convert loaded data to OpenGL texture
-    //----------------------------------------
-    GLuint id;
-    glGenTextures(1, &id);                    // Generate pointer to the texture
-    
-    glBindTexture(GL_TEXTURE_2D, id);
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);     // Filter for pixel-perfect drawing, alternative: GL_LINEAR 
-    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);     // Filter for pixel-perfect drawing, alternative: GL_LINEAR 
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, potWidth, potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixelPOT);
-    
-    // NOTE: Not using mipmappings (texture for 2D drawing)
-    // At this point we have the image converted to texture and uploaded to GPU
-    
-    free(imgDataPixelPOT);                    // Now we can free loaded data from RAM memory
+        // Convert loaded data to OpenGL texture
+        //----------------------------------------
+        GLuint id;
+        glGenTextures(1, &id);                    // Generate pointer to the texture
+        
+        glBindTexture(GL_TEXTURE_2D, id);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);     // Filter for pixel-perfect drawing, alternative: GL_LINEAR 
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);     // Filter for pixel-perfect drawing, alternative: GL_LINEAR 
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, potWidth, potHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixelPOT);
+        
+        // NOTE: Not using mipmappings (texture for 2D drawing)
+        // At this point we have the image converted to texture and uploaded to GPU
+        
+        free(imgDataPixelPOT);                    // Now we can free loaded data from RAM memory
+        
+        spriteFont.texture.glId = id;
+        spriteFont.texture.width = potWidth;
+        spriteFont.texture.height = potHeight;
+    }
     
     
-    spriteFont.texture.glId = id;
-    spriteFont.texture.width = potWidth;
-    spriteFont.texture.height = potHeight;
-
     return spriteFont;
     return spriteFont;
 }
 }
 
 
@@ -289,31 +301,23 @@ void UnloadSpriteFont(SpriteFont spriteFont)
 
 
 // Draw text (using default font)
 // Draw text (using default font)
 // NOTE: fontSize work like in any drawing program but if fontSize is lower than font-base-size, then font-base-size is used
 // NOTE: fontSize work like in any drawing program but if fontSize is lower than font-base-size, then font-base-size is used
+// NOTE: chars spacing is proportional to fontSize
 void DrawText(const char* text, int posX, int posY, int fontSize, Color color)
 void DrawText(const char* text, int posX, int posY, int fontSize, Color color)
 {
 {
     Vector2 position = { (float)posX, (float)posY };
     Vector2 position = { (float)posX, (float)posY };
+       
+    int defaultFontSize = 10;   // Default Font chars height in pixel
     
     
-    DrawTextEx(defaultFont, text, position, fontSize, 1, color);
-}
-
-// Formatting of text with variables to 'embed'
-const char *FormatText(const char *text, ...)
-{
-    int length = strlen(text);
-    char *buffer = malloc(length + 20);  // We add 20 extra characters, should be enough... :P
-
-    va_list args;
-    va_start(args, text);
-    vsprintf(buffer, text, args);        // NOTE: We use vsprintf() defined in <stdarg.h>
-    va_end(args);
+    if (fontSize < defaultFontSize) fontSize = defaultFontSize;
     
     
-    //strcat(buffer, "\0");              // We add a end-of-string mark at the end (not needed)
+    int spacing = fontSize / defaultFontSize;
     
     
-    return buffer;
+    DrawTextEx(defaultFont, text, position, fontSize, spacing, color);
 }
 }
 
 
 // Draw text using SpriteFont
 // Draw text using SpriteFont
 // NOTE: If font size is lower than base size, base size is used
 // NOTE: If font size is lower than base size, base size is used
+// NOTE: chars spacing is NOT proportional to fontSize
 void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint)
 void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint)
 {
 {
     int length = strlen(text);
     int length = strlen(text);
@@ -345,7 +349,7 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
                 glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);     glVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
                 glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);     glVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
                 glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);             glVertex2f(positionX + (c.w) * scaleFactor, position.y);
                 glTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);             glVertex2f(positionX + (c.w) * scaleFactor, position.y);
                 
                 
-                positionX += (spriteFont.charSet[(int)text[i] - FIRST_CHAR].w + spacing) * scaleFactor;
+                positionX += ((spriteFont.charSet[(int)text[i] - FIRST_CHAR].w) * scaleFactor + spacing);
             }
             }
         glEnd();
         glEnd();
         
         
@@ -354,6 +358,22 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
     glDisable(GL_TEXTURE_2D);
     glDisable(GL_TEXTURE_2D);
 }
 }
 
 
+// Formatting of text with variables to 'embed'
+const char *FormatText(const char *text, ...)
+{
+    int length = strlen(text);
+    char *buffer = malloc(length + 20);  // We add 20 extra characters, should be enough... :P
+
+    va_list args;
+    va_start(args, text);
+    vsprintf(buffer, text, args);        // NOTE: We use vsprintf() defined in <stdarg.h>
+    va_end(args);
+    
+    //strcat(buffer, "\0");              // We add a end-of-string mark at the end (not needed)
+    
+    return buffer;
+}
+
 // Measure string width for default font
 // Measure string width for default font
 int MeasureText(const char *text, int fontSize)
 int MeasureText(const char *text, int fontSize)
 {
 {
@@ -517,4 +537,132 @@ static int GetNextPOT(int num)
     }
     }
 
 
     return num;
     return num;
+}
+
+// Load a rBMF font file (raylib BitMap Font)
+static SpriteFont LoadRBMF(const char *fileName)
+{
+    // rBMF Info Header (16 bytes)
+    typedef struct {
+        char id[4];             // rBMF file identifier
+        char version;           // rBMF file version
+                                //      4 MSB --> main version
+                                //      4 LSB --> subversion
+        char firstChar;         // First character in the font
+                                // NOTE: Depending on charDataType, it could be useless
+        short imgWidth;         // Image width - always POT (power-of-two)
+        short imgHeight;        // Image height - always POT (power-of-two)
+        short numChars;         // Number of characters contained
+        short charHeight;       // Characters height - the same for all characters
+        char compType;          // Compression type: 
+                                //      4 MSB --> image data compression
+                                //      4 LSB --> chars data compression
+        char charsDataType;     // Char data type provided
+    } rbmfInfoHeader;
+
+    SpriteFont spriteFont;
+    Image image;
+    
+    rbmfInfoHeader rbmfHeader;
+    unsigned int *rbmfFileData;
+    unsigned char *rbmfCharWidthData;
+    
+    int charsDivisor = 1;    // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
+    
+    FILE *rbmfFile = fopen(fileName, "rb");        // Define a pointer to bitmap file and open it in read-binary mode
+
+    fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
+    
+    //printf("rBMF info: %i %i %i %i\n", rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
+    
+    spriteFont.numChars = (int)rbmfHeader.numChars;
+    
+    image.width = (int)rbmfHeader.imgWidth;
+    image.height = (int)rbmfHeader.imgHeight;
+    
+    int numPixelBits = rbmfHeader.imgWidth * rbmfHeader.imgHeight / 32;
+    
+    rbmfFileData = (unsigned int *)malloc(numPixelBits * sizeof(unsigned int));
+    
+    for(int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile);
+    
+    rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars * sizeof(unsigned char));
+    
+    for(int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile);
+    
+    printf("Just read image data and width data... Starting image reconstruction...");
+    
+    // Re-construct image from rbmfFileData
+    //-----------------------------------------
+    image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
+    
+    for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK;        // Initialize array
+
+    int counter = 0;        // Font data elements counter
+    
+    // Fill image data (convert from bit to pixel!)
+    for (int i = 0; i < image.width * image.height; i += 32)
+    {
+        for (int j = 31; j >= 0; j--)
+        {
+            if (BIT_CHECK(rbmfFileData[counter], j)) image.pixels[i+j] = WHITE;
+        }
+        
+        counter++;
+    }
+    
+    printf("Image reconstructed correctly... now converting it to texture...");
+    
+    spriteFont.texture = CreateTexture2D(image);
+    
+    UnloadImage(image);     // Unload image data
+    
+    printf("Starting charSet reconstruction...\n");
+    
+    // Reconstruct charSet using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
+    spriteFont.charSet = (Character *)malloc(spriteFont.numChars * sizeof(Character));     // Allocate space for our character data
+
+    int currentLine = 0;
+    int currentPosX = charsDivisor;
+    int testPosX = charsDivisor;
+    
+    for (int i = 0; i < spriteFont.numChars; i++)
+    {
+        spriteFont.charSet[i].value = (int)rbmfHeader.firstChar + i;
+        spriteFont.charSet[i].x = currentPosX;
+        spriteFont.charSet[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor);
+        spriteFont.charSet[i].w = (int)rbmfCharWidthData[i];
+        spriteFont.charSet[i].h = (int)rbmfHeader.charHeight;
+        
+        testPosX += (spriteFont.charSet[i].w + charsDivisor);
+        
+        if (testPosX > spriteFont.texture.width)
+        {
+            currentLine++;
+            currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i];
+            testPosX = currentPosX;
+            
+            spriteFont.charSet[i].x = charsDivisor;
+            spriteFont.charSet[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
+        }
+        else currentPosX = testPosX;
+        
+        //printf("Char %i data: %i %i %i %i\n", spriteFont.charSet[i].value, spriteFont.charSet[i].x, spriteFont.charSet[i].y, spriteFont.charSet[i].w, spriteFont.charSet[i].h); 
+    }
+    
+    printf("CharSet reconstructed correctly... Data should be ready...\n");
+    
+    fclose(rbmfFile);
+    
+    free(rbmfFileData);                // Now we can free loaded data from RAM memory
+    free(rbmfCharWidthData);    
+
+    return spriteFont;
+}
+
+static const char *GetExtension(const char *fileName) 
+{
+    const char *dot = strrchr(fileName, '.');
+    if(!dot || dot == fileName) return "";
+    return dot + 1;
 }
 }