Support custom modules inclusion

Allow to choose which modules are compiled with raylib, if some modules are excluded from compilation, required functionality is not available but smaller builds are possible.
This commit is contained in:
Ray 2021-12-04 19:56:02 +01:00
parent 48d4806e53
commit e637ad9d2a
9 changed files with 193 additions and 123 deletions

View File

@ -27,6 +27,13 @@ endif()
option(INCLUDE_EVERYTHING "Include everything disabled by default (for CI usage" OFF)
set(OFF ${INCLUDE_EVERYTHING} CACHE INTERNAL "Replace any OFF by default with \${OFF} to have it covered by this option")
# raylib modules included
cmake_dependent_option(SUPPORT_MODULE_RSHAPES "Include module: rshapes" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RTEXTURES "Include module: rtextures" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RTEXT "Include module: rtext" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RMODELS "Include module: rmodels" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_MODULE_RAUDIO "Include module: raudio" ON CUSTOMIZE_BUILD ON)
# rcore.c
cmake_dependent_option(SUPPORT_CAMERA_SYSTEM "Provide camera module (rcamera.h) with multiple predefined cameras: free, 1st/3rd person, orbital" ON CUSTOMIZE_BUILD ON)
cmake_dependent_option(SUPPORT_GESTURES_SYSTEM "Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag" ON CUSTOMIZE_BUILD ON)

View File

@ -26,7 +26,17 @@
**********************************************************************************************/
//------------------------------------------------------------------------------------
// Module: core - Configuration Flags
// Module selection - Some modules could be avoided
// Mandatory modules: rcore, rlgl, utils
//------------------------------------------------------------------------------------
#define SUPPORT_MODULE_RSHAPES 1
#define SUPPORT_MODULE_RTEXTURES 1
#define SUPPORT_MODULE_RTEXT 1 // WARNING: It requires SUPPORT_MODULE_RTEXTURES to load sprite font textures
#define SUPPORT_MODULE_RMODELS 1
#define SUPPORT_MODULE_RAUDIO 1
//------------------------------------------------------------------------------------
// Module: rcore - Configuration Flags
//------------------------------------------------------------------------------------
// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
#define SUPPORT_CAMERA_SYSTEM 1
@ -62,7 +72,7 @@
// Enabling this flag allows manual control of the frame processes, use at your own risk
//#define SUPPORT_CUSTOM_FRAME_CONTROL 1
// core: Configuration values
// rcore: Configuration values
//------------------------------------------------------------------------------------
#if defined(__linux__)
#define MAX_FILEPATH_LENGTH 4096 // Maximum length for filepaths (Linux PATH_MAX default value)
@ -127,7 +137,7 @@
//------------------------------------------------------------------------------------
// Module: shapes - Configuration Flags
// Module: rshapes - Configuration Flags
//------------------------------------------------------------------------------------
// Use QUADS instead of TRIANGLES for drawing when possible
// Some lines-based shapes could still use lines
@ -135,7 +145,7 @@
//------------------------------------------------------------------------------------
// Module: textures - Configuration Flags
// Module: rtextures - Configuration Flags
//------------------------------------------------------------------------------------
// Selecte desired fileformats to be supported for image data loading
#define SUPPORT_FILEFORMAT_PNG 1
@ -162,7 +172,7 @@
//------------------------------------------------------------------------------------
// Module: text - Configuration Flags
// Module: rtext - Configuration Flags
//------------------------------------------------------------------------------------
// Default font is loaded on window initialization to be available for the user to render simple text
// NOTE: If enabled, uses external module functions to load default raylib font
@ -175,7 +185,7 @@
// If not defined, still some functions are supported: TextLength(), TextFormat()
#define SUPPORT_TEXT_MANIPULATION 1
// text: Configuration values
// rtext: Configuration values
//------------------------------------------------------------------------------------
#define MAX_TEXT_BUFFER_LENGTH 1024 // Size of internal static buffers used on some functions:
// TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit()
@ -183,7 +193,7 @@
//------------------------------------------------------------------------------------
// Module: models - Configuration Flags
// Module: rmodels - Configuration Flags
//------------------------------------------------------------------------------------
// Selected desired model fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_OBJ 1
@ -195,13 +205,13 @@
// NOTE: Some generated meshes DO NOT include generated texture coordinates
#define SUPPORT_MESH_GENERATION 1
// models: Configuration values
// rmodels: Configuration values
//------------------------------------------------------------------------------------
#define MAX_MATERIAL_MAPS 12 // Maximum number of shader maps supported
#define MAX_MESH_VERTEX_BUFFERS 7 // Maximum vertex buffers (VBO) per mesh
//------------------------------------------------------------------------------------
// Module: audio - Configuration Flags
// Module: raudio - Configuration Flags
//------------------------------------------------------------------------------------
// Desired audio fileformats to be supported for loading
#define SUPPORT_FILEFORMAT_WAV 1
@ -211,7 +221,7 @@
#define SUPPORT_FILEFORMAT_MP3 1
//#define SUPPORT_FILEFORMAT_FLAC 1
// audio: Configuration values
// raudio: Configuration values
//------------------------------------------------------------------------------------
#define AUDIO_DEVICE_FORMAT ma_format_f32 // Device output format (miniaudio: float-32bit)
#define AUDIO_DEVICE_CHANNELS 2 // Device output channels: stereo

View File

@ -12,6 +12,9 @@
*
* CONFIGURATION:
*
* #define SUPPORT_MODULE_RAUDIO
* raudio module is included in the build
*
* #define RAUDIO_STANDALONE
* Define to use the module as standalone library (independently of raylib).
* Required types and functions are defined in the same module.
@ -78,6 +81,8 @@
#include "utils.h" // Required for: fopen() Android mapping
#endif
#if defined(SUPPORT_MODULE_RAUDIO)
#if defined(_WIN32)
// To avoid conflicting windows.h symbols with raylib, some flags are defined
// WARNING: Those flags avoid inclusion of some Win32 headers that could be required
@ -169,10 +174,9 @@ typedef struct tagBITMAPINFOHEADER {
#include <stdlib.h> // Required for: malloc(), free()
#include <stdio.h> // Required for: FILE, fopen(), fclose(), fread()
#include <string.h> // Required for: strcmp() [Used in IsFileExtension(), LoadWaveFromMemory(), LoadMusicStreamFromMemory()]
#if defined(RAUDIO_STANDALONE)
#include <string.h> // Required for: strcmp() [Used in IsFileExtension()]
#ifndef TRACELOG
#define TRACELOG(level, ...) (void)0
#endif
@ -374,8 +378,6 @@ static void MixAudioFrames(float *framesOut, const float *framesIn, ma_uint32 fr
#if defined(RAUDIO_STANDALONE)
static bool IsFileExtension(const char *fileName, const char *ext); // Check file extension
static const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes the dot: .png)
static bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
static const char *TextToLower(const char *text); // Get lower case version of provided string
static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
static bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write)
@ -711,16 +713,14 @@ Wave LoadWave(const char *fileName)
}
// Load wave from memory buffer, fileType refers to extension: i.e. ".wav"
// WARNING: File extension must be provided in lower-case
Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int dataSize)
{
Wave wave = { 0 };
char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType));
if (false) { }
#if defined(SUPPORT_FILEFORMAT_WAV)
else if (TextIsEqual(fileExtLower, ".wav"))
else if (strcmp(fileType, ".wav") == 0)
{
drwav wav = { 0 };
bool success = drwav_init_memory(&wav, fileData, dataSize, NULL);
@ -742,7 +742,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
}
#endif
#if defined(SUPPORT_FILEFORMAT_OGG)
else if (TextIsEqual(fileExtLower, ".ogg"))
else if (strcmp(fileType, ".ogg") == 0)
{
stb_vorbis *oggData = stb_vorbis_open_memory((unsigned char *)fileData, dataSize, NULL, NULL);
@ -764,7 +764,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
}
#endif
#if defined(SUPPORT_FILEFORMAT_FLAC)
else if (TextIsEqual(fileExtLower, ".flac"))
else if (strcmp(fileType, ".flac") == 0)
{
unsigned long long int totalFrameCount = 0;
@ -777,7 +777,7 @@ Wave LoadWaveFromMemory(const char *fileType, const unsigned char *fileData, int
}
#endif
#if defined(SUPPORT_FILEFORMAT_MP3)
else if (TextIsEqual(fileExtLower, ".mp3"))
else if (strcmp(fileType, ".mp3") == 0)
{
drmp3_config config = { 0 };
unsigned long long int totalFrameCount = 0;
@ -1377,18 +1377,16 @@ Music LoadMusicStream(const char *fileName)
return music;
}
// extension including period ".mod"
// Load music stream from memory buffer, fileType refers to extension: i.e. ".wav"
// WARNING: File extension must be provided in lower-case
Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int dataSize)
{
Music music = { 0 };
bool musicLoaded = false;
char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType));
if (false) { }
#if defined(SUPPORT_FILEFORMAT_WAV)
else if (TextIsEqual(fileExtLower, ".wav"))
else if (strcmp(fileType, ".wav") == 0)
{
drwav *ctxWav = RL_CALLOC(1, sizeof(drwav));
@ -1410,7 +1408,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
}
#endif
#if defined(SUPPORT_FILEFORMAT_FLAC)
else if (TextIsEqual(fileExtLower, ".flac"))
else if (strcmp(fileType, ".flac") == 0)
{
music.ctxType = MUSIC_AUDIO_FLAC;
music.ctxData = drflac_open_memory((const void*)data, dataSize, NULL);
@ -1427,7 +1425,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
}
#endif
#if defined(SUPPORT_FILEFORMAT_MP3)
else if (TextIsEqual(fileExtLower, ".mp3"))
else if (strcmp(fileType, ".mp3") == 0)
{
drmp3 *ctxMp3 = RL_CALLOC(1, sizeof(drmp3));
int success = drmp3_init_memory(ctxMp3, (const void*)data, dataSize, NULL);
@ -1445,7 +1443,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
}
#endif
#if defined(SUPPORT_FILEFORMAT_OGG)
else if (TextIsEqual(fileExtLower, ".ogg"))
else if (strcmp(fileType, ".ogg") == 0)
{
// Open ogg audio stream
music.ctxType = MUSIC_AUDIO_OGG;
@ -1467,7 +1465,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
}
#endif
#if defined(SUPPORT_FILEFORMAT_XM)
else if (TextIsEqual(fileExtLower, ".xm"))
else if (strcmp(fileType, ".xm") == 0)
{
jar_xm_context_t *ctxXm = NULL;
int result = jar_xm_create_context_safe(&ctxXm, (const char *)data, dataSize, AUDIO.System.device.sampleRate);
@ -1494,7 +1492,7 @@ Music LoadMusicStreamFromMemory(const char *fileType, unsigned char *data, int d
}
#endif
#if defined(SUPPORT_FILEFORMAT_MOD)
else if (TextIsEqual(fileExtLower, ".mod"))
else if (strcmp(fileType, ".mod") == 0)
{
jar_mod_context_t *ctxMod = (jar_mod_context_t *)RL_MALLOC(sizeof(jar_mod_context_t));
int result = 0;
@ -2261,38 +2259,6 @@ static const char *GetFileExtension(const char *fileName)
return dot;
}
// Check if two text string are equal
// REQUIRES: strcmp()
static bool TextIsEqual(const char *text1, const char *text2)
{
bool result = false;
if (strcmp(text1, text2) == 0) result = true;
return result;
}
// Get lower case version of provided string
// REQUIRES: tolower()
static const char *TextToLower(const char *text)
{
#define MAX_TEXT_BUFFER_LENGTH 1024
static char buffer[MAX_TEXT_BUFFER_LENGTH] = { 0 };
for (int i = 0; i < MAX_TEXT_BUFFER_LENGTH; i++)
{
if (text[i] != '\0')
{
buffer[i] = (char)tolower(text[i]);
//if ((text[i] >= 'A') && (text[i] <= 'Z')) buffer[i] = text[i] + 32;
}
else { buffer[i] = '\0'; break; }
}
return buffer;
}
// Load data from file into a buffer
static unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead)
{
@ -2378,3 +2344,5 @@ static bool SaveFileText(const char *fileName, char *text)
#endif
#undef AudioBuffer
#endif // SUPPORT_MODULE_RAUDIO

View File

@ -1031,7 +1031,7 @@ RLAPI void SetLoadFileTextCallback(LoadFileTextCallback callback); // Set custom
RLAPI void SetSaveFileTextCallback(SaveFileTextCallback callback); // Set custom file text data saver
// Files management functions
RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
RLAPI unsigned char *LoadFileData(const char *fileName, unsigned int *bytesRead); // Load file data as byte array (read)
RLAPI void UnloadFileData(unsigned char *data); // Unload file data allocated by LoadFileData()
RLAPI bool SaveFileData(const char *fileName, void *data, unsigned int bytesToWrite); // Save data to file from byte array (write), returns true on success
RLAPI char *LoadFileText(const char *fileName); // Load text data from file (read), returns a '\0' terminated string
@ -1039,7 +1039,7 @@ RLAPI void UnloadFileText(char *text); // Unload file
RLAPI bool SaveFileText(const char *fileName, char *text); // Save text data to file (write), string must be '\0' terminated, returns true on success
RLAPI bool FileExists(const char *fileName); // Check if file exists
RLAPI bool DirectoryExists(const char *dirPath); // Check if a directory path exists
RLAPI bool IsFileExtension(const char *fileName, const char *ext);// Check file extension (including point: .png, .wav)
RLAPI bool IsFileExtension(const char *fileName, const char *ext); // Check file extension (including point: .png, .wav)
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)

View File

@ -588,7 +588,7 @@ static bool eventsRecording = false; // Record events
//----------------------------------------------------------------------------------
// Other Modules Functions Declaration (required by core)
//----------------------------------------------------------------------------------
#if defined(SUPPORT_DEFAULT_FONT)
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
extern void LoadFontDefault(void); // [Module: text] Loads default font on InitWindow()
extern void UnloadFontDefault(void); // [Module: text] Unloads default font from GPU memory
#endif
@ -668,6 +668,10 @@ static void PlayAutomationEvent(unsigned int frame); // Play frame events
void __stdcall Sleep(unsigned long msTimeout); // Required for: WaitTime()
#endif
#if !defined(SUPPORT_MODULE_RTEXT)
const char *TextFormat(const char *text, ...); // Formatting of text with variables to 'embed'
#endif // !SUPPORT_MODULE_RTEXT
//----------------------------------------------------------------------------------
// Module Functions Definition - Window and OpenGL Context Functions
//----------------------------------------------------------------------------------
@ -791,24 +795,30 @@ void InitWindow(int width, int height, const char *title)
// Initialize base path for storage
CORE.Storage.basePath = GetWorkingDirectory();
#if defined(SUPPORT_DEFAULT_FONT)
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
// NOTE: External functions (defined in module: text)
// WARNING: External function: Module required: rtext
LoadFontDefault();
#if defined(SUPPORT_MODULE_RSHAPES)
Rectangle rec = GetFontDefault().recs[95];
// NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); // WARNING: Module required: rshapes
#endif
#else
#if defined(SUPPORT_MODULE_RSHAPES)
// Set default texture and rectangle to be used for shapes drawing
// NOTE: rlgl default texture is a 1x1 pixel UNCOMPRESSED_R8G8B8A8
Texture2D texture = { rlGetTextureIdDefault(), 1, 1, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f });
SetShapesTexture(texture, (Rectangle){ 0.0f, 0.0f, 1.0f, 1.0f }); // WARNING: Module required: rshapes
#endif
#endif
#if defined(PLATFORM_DESKTOP)
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
if ((CORE.Window.flags & FLAG_WINDOW_HIGHDPI) > 0)
{
// Set default font texture filter for HighDPI (blurry)
SetTextureFilter(GetFontDefault().texture, TEXTURE_FILTER_BILINEAR);
// RL_TEXTURE_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MIN_FILTER, RL_TEXTURE_FILTER_LINEAR);
rlTextureParameters(GetFontDefault().texture.id, RL_TEXTURE_MAG_FILTER, RL_TEXTURE_FILTER_LINEAR);
}
#endif
@ -867,8 +877,8 @@ void CloseWindow(void)
}
#endif
#if defined(SUPPORT_DEFAULT_FONT)
UnloadFontDefault();
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
UnloadFontDefault(); // WARNING: Module required: rtext
#endif
rlglClose(); // De-init rlgl
@ -1926,11 +1936,11 @@ void EndDrawing(void)
{
rlDrawRenderBatchActive(); // Update and draw internal render batch
#if defined(SUPPORT_MOUSE_CURSOR_POINT)
#if defined(SUPPORT_MODULE_RSHAPES) && defined(SUPPORT_MOUSE_CURSOR_POINT)
// Draw a small rectangle on mouse position for user reference
if (!CORE.Input.Mouse.cursorHidden)
{
DrawRectangle(CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y, 3, 3, MAROON);
DrawRectangle(CORE.Input.Mouse.currentPosition.x, CORE.Input.Mouse.currentPosition.y, 3, 3, MAROON); // WARNING: Module required: rshapes
rlDrawRenderBatchActive(); // Update and draw internal render batch
}
#endif
@ -1953,11 +1963,13 @@ void EndDrawing(void)
RL_FREE(screenData); // Free image data
}
#if defined(SUPPORT_MODULE_RSHAPES) && defined(SUPPORT_MODULE_RTEXT)
if (((gifFrameCounter/15)%2) == 1)
{
DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON);
DrawText("GIF RECORDING", 50, CORE.Window.screen.height - 25, 10, RED);
DrawCircle(30, CORE.Window.screen.height - 20, 10, MAROON); // WARNING: Module required: rshapes
DrawText("GIF RECORDING", 50, CORE.Window.screen.height - 25, 10, RED); // WARNING: Module required: rtext
}
#endif
rlDrawRenderBatchActive(); // Update and draw internal render batch
}
@ -2665,13 +2677,14 @@ void SetConfigFlags(unsigned int flags)
// Takes a screenshot of current screen (saved a .png)
void TakeScreenshot(const char *fileName)
{
#if defined(SUPPORT_MODULE_RTEXTURES)
unsigned char *imgData = rlReadScreenPixels(CORE.Window.render.width, CORE.Window.render.height);
Image image = { imgData, CORE.Window.render.width, CORE.Window.render.height, 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
char path[2048] = { 0 };
strcpy(path, TextFormat("%s/%s", CORE.Storage.basePath, fileName));
ExportImage(image, path);
ExportImage(image, path); // WARNING: Module required: rtextures
RL_FREE(imgData);
#if defined(PLATFORM_WEB)
@ -2681,6 +2694,9 @@ void TakeScreenshot(const char *fileName)
#endif
TRACELOG(LOG_INFO, "SYSTEM: [%s] Screenshot taken successfully", path);
#else
TRACELOG(LOG_WARNING,"IMAGE: ExportImage() requires module: rtextures");
#endif
}
// Get a random value between min and max (both included)
@ -2730,16 +2746,16 @@ bool IsFileExtension(const char *fileName, const char *ext)
if (fileExt != NULL)
{
#if defined(SUPPORT_TEXT_MANIPULATION)
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_TEXT_MANIPULATION)
int extCount = 0;
const char **checkExts = TextSplit(ext, ';', &extCount);
const char **checkExts = TextSplit(ext, ';', &extCount); // WARNING: Module required: rtext
char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileExt));
strcpy(fileExtLower, TextToLower(fileExt)); // WARNING: Module required: rtext
for (int i = 0; i < extCount; i++)
{
if (TextIsEqual(fileExtLower, TextToLower(checkExts[i])))
if (strcmp(fileExtLower, TextToLower(checkExts[i])) == 0)
{
result = true;
break;
@ -5302,13 +5318,15 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
// Initialize random seed
srand((unsigned int)time(NULL));
#if defined(SUPPORT_DEFAULT_FONT)
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
// Load default font
// NOTE: External function (defined in module: text)
// WARNING: External function: Module required: rtext
LoadFontDefault();
Rectangle rec = GetFontDefault().recs[95];
// NOTE: We setup a 1px padding on char rectangle to avoid pixel bleeding on MSAA filtering
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 });
#if defined(SUPPORT_MODULE_RSHAPES)
SetShapesTexture(GetFontDefault().texture, (Rectangle){ rec.x + 1, rec.y + 1, rec.width - 2, rec.height - 2 }); // WARNING: Module required: rshapes
#endif
#endif
// TODO: GPU assets reload in case of lost focus (lost context)
@ -6776,3 +6794,34 @@ static void PlayAutomationEvent(unsigned int frame)
}
}
#endif
#if !defined(SUPPORT_MODULE_RTEXT)
// Formatting of text with variables to 'embed'
// WARNING: String returned will expire after this function is called MAX_TEXTFORMAT_BUFFERS times
const char *TextFormat(const char *text, ...)
{
#ifndef MAX_TEXTFORMAT_BUFFERS
#define MAX_TEXTFORMAT_BUFFERS 4 // Maximum number of static buffers for text formatting
#endif
#ifndef MAX_TEXT_BUFFER_LENGTH
#define MAX_TEXT_BUFFER_LENGTH 1024 // Maximum size of static text buffer
#endif
// We create an array of buffers so strings don't expire until MAX_TEXTFORMAT_BUFFERS invocations
static char buffers[MAX_TEXTFORMAT_BUFFERS][MAX_TEXT_BUFFER_LENGTH] = { 0 };
static int index = 0;
char *currentBuffer = buffers[index];
memset(currentBuffer, 0, MAX_TEXT_BUFFER_LENGTH); // Clear buffer before using
va_list args;
va_start(args, text);
vsnprintf(currentBuffer, MAX_TEXT_BUFFER_LENGTH, text, args);
va_end(args);
index += 1; // Move to next buffer for next function call
if (index >= MAX_TEXTFORMAT_BUFFERS) index = 0;
return currentBuffer;
}
#endif // !SUPPORT_MODULE_RTEXT

View File

@ -4,12 +4,14 @@
*
* CONFIGURATION:
*
* #define SUPPORT_MODULE_RMODELS
* rmodels module is included in the build
*
* #define SUPPORT_FILEFORMAT_OBJ
* #define SUPPORT_FILEFORMAT_MTL
* #define SUPPORT_FILEFORMAT_IQM
* #define SUPPORT_FILEFORMAT_GLTF
* #define SUPPORT_FILEFORMAT_VOX
*
* Selected desired fileformats to be supported for model data loading.
*
* #define SUPPORT_MESH_GENERATION
@ -45,6 +47,8 @@
#include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RMODELS)
#include "utils.h" // Required for: TRACELOG(), LoadFileData(), LoadFileText(), SaveFileText()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
#include "raymath.h" // Required for: Vector3, Quaternion and Matrix functionality
@ -918,7 +922,7 @@ Model LoadModel(const char *fileName)
if (IsFileExtension(fileName, ".iqm")) model = LoadIQM(fileName);
#endif
#if defined(SUPPORT_FILEFORMAT_GLTF)
if (IsFileExtension(fileName, ".gltf;.glb")) model = LoadGLTF(fileName);
if (IsFileExtension(fileName, ".gltf") || IsFileExtension(fileName, ".glb")) model = LoadGLTF(fileName);
#endif
#if defined(SUPPORT_FILEFORMAT_VOX)
if (IsFileExtension(fileName, ".vox")) model = LoadVOX(fileName);
@ -1704,7 +1708,6 @@ bool ExportMesh(Mesh mesh, const char *fileName)
return success;
}
// Load materials from model file
Material *LoadMaterials(const char *fileName, int *materialCount)
{
@ -5089,3 +5092,5 @@ static Model LoadVOX(const char *fileName)
return model;
}
#endif
#endif // SUPPORT_MODULE_RMODELS

View File

@ -17,6 +17,9 @@
*
* CONFIGURATION:
*
* #define SUPPORT_MODULE_RSHAPES
* rshapes module is included in the build
*
* #define SUPPORT_QUADS_DRAW_MODE
* Use QUADS instead of TRIANGLES for drawing when possible. Lines-based shapes still use LINES
*
@ -49,6 +52,8 @@
#include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RSHAPES)
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2
#include <math.h> // Required for: sinf(), asinf(), cosf(), acosf(), sqrtf(), fabsf()
@ -75,8 +80,8 @@
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
Texture2D texShapes = { 1, 1, 1, 1, 7 }; // Texture used on shapes drawing (usually a white pixel)
Rectangle texShapesRec = { 0, 0, 1, 1 }; // Texture source rectangle used on shapes drawing
Texture2D texShapes = { 1, 1, 1, 1, 7 }; // Texture used on shapes drawing (usually a white pixel)
Rectangle texShapesRec = { 0.0f, 0.0f, 1.0f, 1.0f }; // Texture source rectangle used on shapes drawing
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
@ -1810,3 +1815,5 @@ static float EaseCubicInOut(float t, float b, float c, float d)
return 0.5f*c*(t*t*t + 2.0f) + b;
}
#endif // SUPPORT_MODULE_RSHAPES

View File

@ -4,6 +4,9 @@
*
* CONFIGURATION:
*
* #define SUPPORT_MODULE_RTEXT
* rtext module is included in the build
*
* #define SUPPORT_FILEFORMAT_FNT
* #define SUPPORT_FILEFORMAT_TTF
* Selected desired fileformats to be supported for loading. Some of those formats are
@ -53,6 +56,8 @@
#include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RTEXT)
#include "utils.h" // Required for: LoadFileText()
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 2.1, 3.3+ or ES2 -> Only DrawTextPro()
@ -311,7 +316,7 @@ Font LoadFont(const char *fileName)
Font font = { 0 };
#if defined(SUPPORT_FILEFORMAT_TTF)
if (IsFileExtension(fileName, ".ttf;.otf")) font = LoadFontEx(fileName, FONT_TTF_DEFAULT_SIZE, NULL, FONT_TTF_DEFAULT_NUMCHARS);
if (IsFileExtension(fileName, ".ttf") || IsFileExtension(fileName, ".otf")) font = LoadFontEx(fileName, FONT_TTF_DEFAULT_SIZE, NULL, FONT_TTF_DEFAULT_NUMCHARS);
else
#endif
#if defined(SUPPORT_FILEFORMAT_FNT)
@ -1795,3 +1800,5 @@ static Font LoadBMFont(const char *fileName)
return font;
}
#endif
#endif // SUPPORT_MODULE_RTEXT

View File

@ -4,6 +4,9 @@
*
* CONFIGURATION:
*
* #define SUPPORT_MODULE_RTEXTURES
* rtextures module is included in the build
*
* #define SUPPORT_FILEFORMAT_BMP
* #define SUPPORT_FILEFORMAT_PNG
* #define SUPPORT_FILEFORMAT_TGA
@ -65,11 +68,13 @@
#include "config.h" // Defines module configuration flags
#endif
#if defined(SUPPORT_MODULE_RTEXTURES)
#include "utils.h" // Required for: TRACELOG() and fopen() Android mapping
#include "rlgl.h" // OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
#include <stdlib.h> // Required for: malloc(), free()
#include <string.h> // Required for: strlen() [Used in ImageTextEx()]
#include <string.h> // Required for: strlen() [Used in ImageTextEx()], strcmp() [Used in LoadImageFromMemory()]
#include <math.h> // Required for: fabsf()
#include <stdio.h> // Required for: sprintf() [Used in ExportImageAsCode()]
@ -296,36 +301,33 @@ Image LoadImageAnim(const char *fileName, int *frames)
}
// Load image from memory buffer, fileType refers to extension: i.e. ".png"
// WARNING: File extension must be provided in lower-case
Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, int dataSize)
{
Image image = { 0 };
char fileExtLower[16] = { 0 };
strcpy(fileExtLower, TextToLower(fileType));
#if defined(SUPPORT_FILEFORMAT_PNG)
if ((TextIsEqual(fileExtLower, ".png"))
if ((strcmp(fileType, ".png") == 0)
#else
if ((false)
#endif
#if defined(SUPPORT_FILEFORMAT_BMP)
|| (TextIsEqual(fileExtLower, ".bmp"))
|| (strcmp(fileType, ".bmp") == 0)
#endif
#if defined(SUPPORT_FILEFORMAT_TGA)
|| (TextIsEqual(fileExtLower, ".tga"))
|| (strcmp(fileType, ".tga") == 0)
#endif
#if defined(SUPPORT_FILEFORMAT_JPG)
|| (TextIsEqual(fileExtLower, ".jpg") ||
TextIsEqual(fileExtLower, ".jpeg"))
|| ((strcmp(fileType, ".jpg") == 0) || (strcmp(fileType, ".jpeg") == 0))
#endif
#if defined(SUPPORT_FILEFORMAT_GIF)
|| (TextIsEqual(fileExtLower, ".gif"))
|| (strcmp(fileType, ".gif") == 0)
#endif
#if defined(SUPPORT_FILEFORMAT_PIC)
|| (TextIsEqual(fileExtLower, ".pic"))
|| (strcmp(fileType, ".pic") == 0)
#endif
#if defined(SUPPORT_FILEFORMAT_PSD)
|| (TextIsEqual(fileExtLower, ".psd"))
|| (strcmp(fileType, ".psd") == 0)
#endif
)
{
@ -350,7 +352,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
#endif
}
#if defined(SUPPORT_FILEFORMAT_HDR)
else if (TextIsEqual(fileExtLower, ".hdr"))
else if (strcmp(fileType, ".hdr") == 0)
{
#if defined(STBI_REQUIRED)
if (fileData != NULL)
@ -373,7 +375,7 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
}
#endif
#if defined(SUPPORT_FILEFORMAT_QOI)
else if (TextIsEqual(fileExtLower, ".qoi"))
else if (strcmp(fileType, ".qoi") == 0)
{
qoi_desc desc = { 0 };
image.data = qoi_decode(fileData, dataSize, &desc, 4);
@ -384,19 +386,19 @@ Image LoadImageFromMemory(const char *fileType, const unsigned char *fileData, i
}
#endif
#if defined(SUPPORT_FILEFORMAT_DDS)
else if (TextIsEqual(fileExtLower, ".dds")) image = LoadDDS(fileData, dataSize);
else if (strcmp(fileType, ".dds") == 0) image = LoadDDS(fileData, dataSize);
#endif
#if defined(SUPPORT_FILEFORMAT_PKM)
else if (TextIsEqual(fileExtLower, ".pkm")) image = LoadPKM(fileData, dataSize);
else if (strcmp(fileType, ".pkm") == 0) image = LoadPKM(fileData, dataSize);
#endif
#if defined(SUPPORT_FILEFORMAT_KTX)
else if (TextIsEqual(fileExtLower, ".ktx")) image = LoadKTX(fileData, dataSize);
else if (strcmp(fileType, ".ktx") == 0) image = LoadKTX(fileData, dataSize);
#endif
#if defined(SUPPORT_FILEFORMAT_PVR)
else if (TextIsEqual(fileExtLower, ".pvr")) image = LoadPVR(fileData, dataSize);
else if (strcmp(fileType, ".pvr") == 0) image = LoadPVR(fileData, dataSize);
#endif
#if defined(SUPPORT_FILEFORMAT_ASTC)
else if (TextIsEqual(fileExtLower, ".astc")) image = LoadASTC(fileData, dataSize);
else if (strcmp(fileType, ".astc") == 0) image = LoadASTC(fileData, dataSize);
#endif
else TRACELOG(LOG_WARNING, "IMAGE: Data format not supported");
@ -1133,35 +1135,41 @@ void ImageToPOT(Image *image, Color fill)
// Create an image from text (default font)
Image ImageText(const char *text, int fontSize, Color color)
{
Image imText = { 0 };
#if defined(SUPPORT_MODULE_RTEXT)
int defaultFontSize = 10; // Default Font chars height in pixel
if (fontSize < defaultFontSize) fontSize = defaultFontSize;
int spacing = fontSize/defaultFontSize;
Image imText = ImageTextEx(GetFontDefault(), text, (float)fontSize, (float)spacing, color);
imText = ImageTextEx(GetFontDefault(), text, (float)fontSize, (float)spacing, color); // WARNING: Module required: rtext
#else
imText = GenImageColor(200, 60, BLACK); // Generating placeholder black image rectangle
TRACELOG(LOG_WARNING, "IMAGE: ImageTextEx() requires module: rtext");
#endif
return imText;
}
// Create an image from text (custom sprite font)
Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Color tint)
{
Image imText = { 0 };
#if defined(SUPPORT_MODULE_RTEXT)
int size = (int)strlen(text); // Get size in bytes of text
int textOffsetX = 0; // Image drawing position X
int textOffsetY = 0; // Offset between lines (on line break '\n')
// NOTE: Text image is generated at font base size, later scaled to desired font size
Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing);
Vector2 imSize = MeasureTextEx(font, text, (float)font.baseSize, spacing); // WARNING: Module required: rtext
// Create image to store text
Image imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
imText = GenImageColor((int)imSize.x, (int)imSize.y, BLANK);
for (int i = 0; i < size; i++)
{
// Get next codepoint from byte string and glyph index in font
int codepointByteCount = 0;
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
int index = GetGlyphIndex(font, codepoint);
int codepoint = GetCodepoint(&text[i], &codepointByteCount); // WARNING: Module required: rtext
int index = GetGlyphIndex(font, codepoint); // WARNING: Module required: rtext
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
@ -1196,10 +1204,14 @@ Image ImageTextEx(Font font, const char *text, float fontSize, float spacing, Co
TRACELOG(LOG_INFO, "IMAGE: Text scaled by factor: %f", scaleFactor);
// Using nearest-neighbor scaling algorithm for default font
// WARNING: Module required: rtext
if (font.texture.id == GetFontDefault().texture.id) ImageResizeNN(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
else ImageResize(&imText, (int)(imSize.x*scaleFactor), (int)(imSize.y*scaleFactor));
}
#else
imText = GenImageColor(200, 60, BLACK); // Generating placeholder black image rectangle
TRACELOG(LOG_WARNING, "IMAGE: ImageTextEx() requires module: rtext");
#endif
return imText;
}
@ -2809,10 +2821,13 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec, Color
// Draw text (default font) within an image (destination)
void ImageDrawText(Image *dst, const char *text, int posX, int posY, int fontSize, Color color)
{
#if defined(SUPPORT_MODULE_RTEXT)
Vector2 position = { (float)posX, (float)posY };
// NOTE: For default font, sapcing is set to desired font size / default font size (10)
ImageDrawTextEx(dst, GetFontDefault(), text, position, (float)fontSize, (float)fontSize/10, color);
// NOTE: For default font, spacing is set to desired font size / default font size (10)
ImageDrawTextEx(dst, GetFontDefault(), text, position, (float)fontSize, (float)fontSize/10, color); // WARNING: Module required: rtext
#else
TRACELOG(LOG_WARNING, "IMAGE: ImageDrawText() requires module: rtext");
#endif
}
// Draw text (custom sprite font) within an image (destination)
@ -4803,3 +4818,5 @@ static Vector4 *LoadImageDataNormalized(Image image)
return pixels;
}
#endif // SUPPORT_MODULE_RTEXTURES