Update to version 1.0.3
View CHANGELOG for full list of changes
17
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)
|
||||||
|
|
11
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
|
||||||
|
|
|
@ -18,10 +18,28 @@ 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)
|
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||||
SpriteFont font = LoadSpriteFont("resources/custom_font.png"); // SpriteFont loading
|
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...
|
DrawTextEx(font1, msg1, fontPosition1, GetFontBaseSize(font1), -3, WHITE);
|
||||||
// TIP: Use DrawTextEx() function
|
DrawTextEx(font2, msg2, fontPosition2, GetFontBaseSize(font2), -2, WHITE);
|
||||||
/*
|
DrawTextEx(font3, msg3, fontPosition3, GetFontBaseSize(font3), 2, WHITE);
|
||||||
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint);
|
|
||||||
*/
|
|
||||||
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
Normal file
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 19 KiB |
|
@ -9,19 +9,26 @@
|
||||||
*
|
*
|
||||||
********************************************************************************************/
|
********************************************************************************************/
|
||||||
|
|
||||||
#include "raylib.h"
|
#include "../raylib.h"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
int screenWidth = 800;
|
int screenWidth = 560;
|
||||||
int screenHeight = 450;
|
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...
|
DrawTextEx(font1, "TESTING ALAGARD FONT", (Vector2){ 100, 100 }, GetFontBaseSize(font1)*2, 2, MAROON);
|
||||||
// TIP: Use DrawTextEx() function
|
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);
|
||||||
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint);
|
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
Normal file
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 14 KiB |
|
@ -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
|
||||||
|
|
BIN
examples/resources/fonts/alagard.rbmf
Normal file
BIN
examples/resources/fonts/alpha_beta.rbmf
Normal file
BIN
examples/resources/fonts/custom_alagard.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
examples/resources/fonts/custom_jupiter_crash.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
examples/resources/fonts/custom_mecha.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
examples/resources/fonts/jupiter_crash.rbmf
Normal file
BIN
examples/resources/fonts/mecha.rbmf
Normal file
BIN
examples/resources/fonts/pixantiqua.rbmf
Normal file
BIN
examples/resources/fonts/pixelplay.rbmf
Normal file
BIN
examples/resources/fonts/romulus.rbmf
Normal file
BIN
examples/resources/fonts/setback.rbmf
Normal file
BIN
examples/resources/mouse.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
fonts/alagard.rbmf
Normal file
BIN
fonts/alpha_beta.rbmf
Normal file
BIN
fonts/jupiter_crash.rbmf
Normal file
BIN
fonts/mecha.rbmf
Normal file
BIN
fonts/pixantiqua.rbmf
Normal file
BIN
fonts/pixelplay.rbmf
Normal file
BIN
fonts/romulus.rbmf
Normal file
BIN
fonts/setback.rbmf
Normal file
|
@ -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 DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
|
||||||
void DrawPolyLine(Vector2 *points, int numPoints, Color color); // Draw polygon lines
|
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
|
||||||
|
|
73
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);
|
printf(description);
|
||||||
fprintf(stderr, "%s", 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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
15
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 DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
|
||||||
void DrawPolyLine(Vector2 *points, int numPoints, Color color); // Draw polygon lines
|
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
|
||||||
|
|
75
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);
|
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
|
||||||
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();
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
|
312
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!
|
// Check file extension
|
||||||
int imgWidth;
|
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
|
||||||
int imgHeight;
|
else
|
||||||
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];
|
// Use stb_image to load image data!
|
||||||
imgDataPixel[pix].g = imgData[i+1];
|
int imgWidth;
|
||||||
imgDataPixel[pix].b = imgData[i+2];
|
int imgHeight;
|
||||||
imgDataPixel[pix].a = imgData[i+3];
|
int imgBpp;
|
||||||
pix++;
|
|
||||||
}
|
|
||||||
|
|
||||||
stbi_image_free(imgData);
|
byte *imgData = stbi_load(fileName, &imgWidth, &imgHeight, &imgBpp, 4); // Force loading to 4 components (RGBA)
|
||||||
|
|
||||||
// At this point we have a pixel array with all the data...
|
// Convert array to pixel array for working convenience
|
||||||
|
Color *imgDataPixel = (Color *)malloc(imgWidth * imgHeight * sizeof(Color));
|
||||||
|
Color *imgDataPixelPOT = NULL;
|
||||||
|
|
||||||
// Process bitmap Font pixel data to get measures (Character array)
|
int pix = 0;
|
||||||
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
|
||||||
int numChars = ParseImageData(imgDataPixel, imgWidth, imgHeight, &spriteFont.charSet);
|
|
||||||
|
|
||||||
spriteFont.numChars = numChars;
|
for (int i = 0; i < (imgWidth * imgHeight * 4); i += 4)
|
||||||
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
for (int j = 0; j < potHeight; j++)
|
|
||||||
{
|
{
|
||||||
for (int i = 0; i < potWidth; i++)
|
imgDataPixel[pix].r = imgData[i];
|
||||||
{
|
imgDataPixel[pix].g = imgData[i+1];
|
||||||
if ((j < imgHeight) && (i < imgWidth)) imgDataPixelPOT[j*potWidth + i] = imgDataPixel[j*imgWidth + i];
|
imgDataPixel[pix].b = imgData[i+2];
|
||||||
else imgDataPixelPOT[j*potWidth + i] = MAGENTA;
|
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++)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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 };
|
||||||
|
|
||||||
DrawTextEx(defaultFont, text, position, fontSize, 1, color);
|
int defaultFontSize = 10; // Default Font chars height in pixel
|
||||||
}
|
|
||||||
|
|
||||||
// Formatting of text with variables to 'embed'
|
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
|
||||||
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;
|
int spacing = fontSize / defaultFontSize;
|
||||||
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)
|
DrawTextEx(defaultFont, text, position, fontSize, spacing, color);
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
@ -518,3 +538,131 @@ 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;
|
||||||
|
}
|