Просмотр исходного кода

Update to version 1.0.3

View CHANGELOG for full list of changes
raysan5 11 лет назад
Родитель
Сommit
5bf9675d38
40 измененных файлов с 470 добавлено и 147 удалено
  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
 ---------
 
-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: 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)

+ 10 - 1
LICENSE.md

@@ -27,4 +27,13 @@ applications, and to alter it and redistribute it freely, subject to the followi
 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 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");
     
-    // 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
@@ -29,7 +47,7 @@ int main()
     {
         // Update
         //----------------------------------------------------------------------------------
-        // TODO: Update your variables here
+        // TODO: Update variables here...
         //----------------------------------------------------------------------------------
         
         // Draw
@@ -38,18 +56,19 @@ int main()
         
             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();
         //----------------------------------------------------------------------------------
     }
 
     // De-Initialization
     //--------------------------------------------------------------------------------------
-    UnloadSpriteFont(font);       // SpriteFont unloading
+    UnloadSpriteFont(font1);      // SpriteFont unloading
+    UnloadSpriteFont(font2);      // SpriteFont unloading
+    UnloadSpriteFont(font3);      // SpriteFont unloading
     
     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()
 {
     // 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)
-    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
@@ -38,20 +45,31 @@ int main()
         
             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();
         //----------------------------------------------------------------------------------
     }
 
     // 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;

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
     
-    Sound fx = LoadSound("resources/weird.wav");         // Load WAV audio file
+    Sound fx = LoadSound("resources/audio/weird.wav");         // Load WAV audio file
     //--------------------------------------------------------------------------------------
     
     // 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
 *
@@ -236,10 +236,13 @@ extern "C" {            // Prevents name mangling of functions
 //------------------------------------------------------------------------------------
 // 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
 bool WindowShouldClose();                               // Detect if KEY_ESCAPE pressed or Close icon pressed
 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 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
 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)
 //------------------------------------------------------------------------------------
@@ -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 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 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 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 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 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

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 <GL/gl.h>        // OpenGL functions (GLFW3 already includes gl.h)
 #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 "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 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 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 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 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 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)
@@ -93,13 +100,21 @@ static void TakeScreenshot();
 //----------------------------------------------------------------------------------
 
 // 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);
     
     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);
     
@@ -114,6 +129,7 @@ void InitWindow(int width, int height, char* title)
     }
     
     glfwSetWindowSizeCallback(window, WindowSizeCallback);
+    glfwSetCursorEnterCallback(window, CursorEnterCallback);
     
     glfwMakeContextCurrent(window);
     glfwSetKeyCallback(window, KeyCallback);
@@ -125,6 +141,17 @@ void InitWindow(int width, int height, char* title)
     previousTime = glfwGetTime();
 
     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
@@ -136,6 +163,24 @@ void CloseWindow()
     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
 bool WindowShouldClose()
 {
@@ -197,6 +242,8 @@ void BeginDrawing()
 // End canvas drawing and Swap Buffers (Double Buffering)
 void EndDrawing()
 {
+    if (customCursor && cursorOnScreen) DrawTexture(cursor, GetMouseX(), GetMouseY(), WHITE);
+
     glfwSwapBuffers(window);            // Swap back and front buffers
     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);
 }
 
+// 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
 //----------------------------------------------------------------------------------
@@ -529,14 +582,14 @@ bool IsGamepadButtonUp(int gamepad, int button)
 // GLFW3 Error Callback, runs on GLFW3 error
 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
 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);
         
@@ -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
 static void WindowSizeCallback(GLFWwindow* window, int width, int height)
 {
@@ -688,4 +747,4 @@ static void TakeScreenshot()
     free(imgDataPixel);
     
     shotNum++;
-}
+}

+ 2 - 6
src/models.c

@@ -181,8 +181,6 @@ void DrawSphereWires(Vector3 centerPos, float radius, Color color)
 // 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!
 {
-    static int count = 0;
-    
     Vector3 a = { position.x, position.y + height, position.z };
     Vector3 d = { 0.0f, 1.0f, 0.0f };
     Vector3 p;
@@ -202,7 +200,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
         
         glPushMatrix();
             //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);
             
             // Draw cone top
@@ -239,7 +237,7 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
     {
         glPushMatrix();
             //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);
 
             // Draw cylinder top (pointed cap)
@@ -290,8 +288,6 @@ void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float h
             
         glPopMatrix();
     }
-    
-    count += 1;
 }
 
 // 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
 *
@@ -236,10 +236,13 @@ extern "C" {            // Prevents name mangling of functions
 //------------------------------------------------------------------------------------
 // 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
 bool WindowShouldClose();                               // Detect if KEY_ESCAPE pressed or Close icon pressed
 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 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
 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)
 //------------------------------------------------------------------------------------
@@ -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 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 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 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 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 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

+ 60 - 15
src/shapes.c

@@ -102,23 +102,13 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
 }
 
 // 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)
 {
     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);
     
@@ -283,9 +273,30 @@ void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color)
     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
 // 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)
     {
@@ -307,7 +318,7 @@ void DrawPoly(Vector2 *points, int numPoints, Color color)
 
 // Draw polygon lines
 // 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)
     {
@@ -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
 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
 //----------------------------------------------------------------------------------
-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 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
@@ -203,80 +205,90 @@ SpriteFont LoadSpriteFont(const char* fileName)
 {
     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;
 }
 
@@ -289,31 +301,23 @@ void UnloadSpriteFont(SpriteFont spriteFont)
 
 // 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: chars spacing is proportional to fontSize
 void DrawText(const char* text, int posX, int posY, int fontSize, Color color)
 {
     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
 // 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)
 {
     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 / 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();
         
@@ -354,6 +358,22 @@ void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int f
     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
 int MeasureText(const char *text, int fontSize)
 {
@@ -517,4 +537,132 @@ static int GetNextPOT(int 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;
 }