diff options
| author | Indrajith K L | 2025-11-03 17:48:56 +0530 |
|---|---|---|
| committer | Indrajith K L | 2025-11-03 17:48:56 +0530 |
| commit | 737214b71be8fe5fdf51155ad50bb064b3156bd3 (patch) | |
| tree | 21a2713d03830b21ee2b3ffd919708b054728e40 /src | |
| parent | 3afcbd32001fc2ab2dcee1553268dbb39dabf070 (diff) | |
| download | reilua-enhanced-737214b71be8fe5fdf51155ad50bb064b3156bd3.tar.gz reilua-enhanced-737214b71be8fe5fdf51155ad50bb064b3156bd3.tar.bz2 reilua-enhanced-737214b71be8fe5fdf51155ad50bb064b3156bd3.zip | |
Add embedded assets, splash screens, and asset loading support
Features added:
- Embedded main.lua and Lua files support (EMBED_MAIN option)
- Embedded assets support (EMBED_ASSETS option)
- Splash screens with dual logo display (always embedded)
- Asset loading progress tracking API (BeginAssetLoading, UpdateAssetLoading, EndAssetLoading)
- Custom font embedding for splash/loading screens
- --log flag for Windows console control
- --no-logo flag to skip splash screens in development
- Python scripts for embedding (embed_lua.py, embed_assets.py, embed_logo.py, embed_font.py)
- Documentation (EMBEDDING.md, ASSET_LOADING.md, SPLASH_SCREENS.md)
This allows building single-executable releases with all Lua code and assets embedded.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core.c | 61 | ||||
| -rw-r--r-- | src/lua_core.c | 236 | ||||
| -rw-r--r-- | src/main.c | 114 | ||||
| -rw-r--r-- | src/splash.c | 198 |
4 files changed, 587 insertions, 22 deletions
@@ -4,6 +4,14 @@ #include "textures.h" #include "lua_core.h" +/* Forward declarations from lua_core.c for asset loading */ +extern int g_totalAssets; +extern int g_loadedAssets; +extern char g_currentAssetName[256]; +extern bool g_showLoadingScreen; +extern float g_loadingProgress; +extern void drawLoadingScreen(); + static size_t getBufferElementSize( Buffer* buffer ) { switch ( buffer->type ) { case BUFFER_UNSIGNED_CHAR: return sizeof( unsigned char ); @@ -1956,6 +1964,59 @@ int lcoreGetApplicationDirectory( lua_State* L ) { } /* +> RL.BeginAssetLoading( int totalAssets ) + +Initialize asset loading progress tracking + +- totalAssets: Total number of assets to load +*/ +int lcoreBeginAssetLoading( lua_State* L ) { + g_totalAssets = luaL_checkinteger( L, 1 ); + g_loadedAssets = 0; + g_showLoadingScreen = true; + g_loadingProgress = 0.0f; + g_currentAssetName[0] = '\0'; + + return 0; +} + +/* +> RL.UpdateAssetLoading( string assetName ) + +Update loading progress for current asset + +- assetName: Name of the asset currently being loaded +*/ +int lcoreUpdateAssetLoading( lua_State* L ) { + const char* assetName = luaL_checkstring( L, 1 ); + strncpy( g_currentAssetName, assetName, sizeof(g_currentAssetName) - 1 ); + g_currentAssetName[sizeof(g_currentAssetName) - 1] = '\0'; + + g_loadedAssets++; + g_loadingProgress = (float)g_loadedAssets / (float)g_totalAssets; + + if ( g_showLoadingScreen ) { + drawLoadingScreen(); + } + + return 0; +} + +/* +> RL.EndAssetLoading() + +Finish asset loading and hide loading screen +*/ +int lcoreEndAssetLoading( lua_State* L ) { + g_showLoadingScreen = false; + g_totalAssets = 0; + g_loadedAssets = 0; + g_currentAssetName[0] = '\0'; + + return 0; +} + +/* > success = RL.MakeDirectory( string dirPath ) Create directories (including full path requested), returns 0 on success diff --git a/src/lua_core.c b/src/lua_core.c index c619b9c..a6c2ef7 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -15,6 +15,21 @@ #include "reasings.h" #include "bitwiseOp.h" +#ifdef EMBED_MAIN + #include "embedded_main.h" +#endif + +#ifdef EMBED_ASSETS + #include "embedded_assets.h" +#endif + +/* Asset loading progress tracking (non-static so core.c can access) */ +int g_totalAssets = 0; +int g_loadedAssets = 0; +char g_currentAssetName[256] = { '\0' }; +bool g_showLoadingScreen = false; +float g_loadingProgress = 0.0f; + #ifdef PLATFORM_DESKTOP #include "platforms/core_desktop_glfw.c" #elif PLATFORM_DESKTOP_SDL2 @@ -25,6 +40,152 @@ #include "platforms/core_web.c" #endif +/* Draw a nice loading screen with progress bar (non-static so core.c can call it) */ +void drawLoadingScreen() { + int screenWidth = GetScreenWidth(); + int screenHeight = GetScreenHeight(); + + BeginDrawing(); + ClearBackground( BLACK ); + + int centerX = screenWidth / 2; + int centerY = screenHeight / 2; + + const char* title = "LOADING"; + int titleSize = 32; + int titleWidth = MeasureText( title, titleSize ); + + DrawText( title, centerX - titleWidth / 2, centerY - 80, titleSize, WHITE ); + + static float dotTime = 0.0f; + dotTime += 0.016f; + int dotCount = (int)(dotTime * 2.0f) % 4; + + int dotStartX = centerX + titleWidth / 2 + 10; + int dotY = centerY - 80 + titleSize - 12; + for ( int i = 0; i < dotCount; i++ ) { + DrawRectangle( dotStartX + i * 8, dotY, 4, 4, WHITE ); + } + + int barWidth = 200; + int barHeight = 16; + int barX = centerX - barWidth / 2; + int barY = centerY; + + DrawRectangle( barX - 2, barY - 2, barWidth + 4, barHeight + 4, WHITE ); + DrawRectangle( barX, barY, barWidth, barHeight, BLACK ); + + int fillWidth = (int)(barWidth * g_loadingProgress); + if ( fillWidth > 0 ) { + DrawRectangle( barX, barY, fillWidth, barHeight, WHITE ); + + for ( int y = 0; y < barHeight; y += 2 ) { + for ( int x = 0; x < fillWidth; x += 4 ) { + if ( (x + y) % 4 == 0 ) { + DrawRectangle( barX + x, barY + y, 1, 1, BLACK ); + } + } + } + } + + if ( g_totalAssets > 0 ) { + char progressText[32]; + sprintf( progressText, "%d/%d", g_loadedAssets, g_totalAssets ); + int progressWidth = MeasureText( progressText, 16 ); + DrawText( progressText, centerX - progressWidth / 2, barY + barHeight + 12, 16, WHITE ); + } + + if ( g_currentAssetName[0] != '\0' ) { + int assetNameWidth = MeasureText( g_currentAssetName, 10 ); + DrawText( g_currentAssetName, centerX - assetNameWidth / 2, barY + barHeight + 36, 10, WHITE ); + } + + int cornerSize = 8; + int margin = 40; + + DrawRectangle( margin, margin, cornerSize, 2, WHITE ); + DrawRectangle( margin, margin, 2, cornerSize, WHITE ); + + DrawRectangle( screenWidth - margin - cornerSize, margin, cornerSize, 2, WHITE ); + DrawRectangle( screenWidth - margin - 2, margin, 2, cornerSize, WHITE ); + + DrawRectangle( margin, screenHeight - margin - cornerSize, 2, cornerSize, WHITE ); + DrawRectangle( margin, screenHeight - margin - 2, cornerSize, 2, WHITE ); + + DrawRectangle( screenWidth - margin - cornerSize, screenHeight - margin - 2, cornerSize, 2, WHITE ); + DrawRectangle( screenWidth - margin - 2, screenHeight - margin - cornerSize, 2, cornerSize, WHITE ); + + EndDrawing(); +} + +#ifdef EMBED_MAIN +/* Custom loader for embedded Lua files */ +static int embedded_lua_loader( lua_State* L ) { + const char* name = lua_tostring( L, 1 ); + if ( name == NULL ) return 0; + + for ( int i = 0; i < embedded_lua_file_count; i++ ) { + const EmbeddedLuaFile* file = &embedded_lua_files[i]; + + const char* basename = file->name; + size_t name_len = strlen( name ); + size_t base_len = strlen( basename ); + + if ( strcmp( basename, name ) == 0 || + ( base_len > 4 && strcmp( basename + base_len - 4, ".lua" ) == 0 && + strncmp( basename, name, base_len - 4 ) == 0 && name_len == base_len - 4 ) ) { + + if ( luaL_loadbuffer( L, (const char*)file->data, file->size, file->name ) == 0 ) { + return 1; + } + else { + lua_pushfstring( L, "\n\tembedded loader error: %s", lua_tostring( L, -1 ) ); + return 1; + } + } + } + + lua_pushfstring( L, "\n\tno embedded file '%s'", name ); + return 1; +} +#endif + +#ifdef EMBED_ASSETS +/* Helper function to find embedded asset by name */ +static const EmbeddedAsset* find_embedded_asset( const char* name ) { + if ( name == NULL ) return NULL; + + for ( int i = 0; i < embedded_asset_count; i++ ) { + if ( strcmp( embedded_assets[i].name, name ) == 0 ) { + return &embedded_assets[i]; + } + } + return NULL; +} + +/* Override LoadFileData to check embedded assets first */ +unsigned char* LoadFileData_Embedded( const char* fileName, int* dataSize ) { + const EmbeddedAsset* asset = find_embedded_asset( fileName ); + if ( asset != NULL ) { + *dataSize = asset->size; + unsigned char* data = (unsigned char*)malloc( asset->size ); + if ( data != NULL ) { + memcpy( data, asset->data, asset->size ); + } + return data; + } + return LoadFileData( fileName, dataSize ); +} + +/* Check if file exists in embedded assets */ +bool FileExists_Embedded( const char* fileName ) { + if ( find_embedded_asset( fileName ) != NULL ) { + return true; + } + return FileExists( fileName ); +} +#endif + /* Custom implementation since LuaJIT doesn't have lua_geti. */ static void lua_getiCustom( lua_State* L, int index, int i ) { lua_pushinteger( L, i ); // Push the index onto the stack @@ -1446,11 +1607,51 @@ int luaTraceback( lua_State* L ) { return 1; } -void luaCallMain() { +bool luaCallMain() { lua_State* L = state->luaState; char path[ STRING_LEN ] = { '\0' }; + /* Show loading screen */ + BeginDrawing(); + ClearBackground( RAYWHITE ); + const char* loadingText = "Loading..."; + int fontSize = 40; + int textWidth = MeasureText( loadingText, fontSize ); + DrawText( loadingText, ( GetScreenWidth() - textWidth ) / 2, GetScreenHeight() / 2 - fontSize / 2, fontSize, DARKGRAY ); + EndDrawing(); + +#ifdef EMBED_MAIN + /* Register custom loader for embedded files */ + lua_getglobal( L, "package" ); + lua_getfield( L, -1, "loaders" ); + if ( lua_isnil( L, -1 ) ) { + lua_pop( L, 1 ); + lua_getfield( L, -1, "searchers" ); /* Lua 5.2+ uses 'searchers' */ + } + + /* Insert our loader at position 2 (before file loaders) */ + lua_len( L, -1 ); + int num_loaders = lua_tointeger( L, -1 ); + lua_pop( L, 1 ); + for ( int i = num_loaders; i >= 2; i-- ) { + lua_rawgeti( L, -1, i ); + lua_rawseti( L, -2, i + 1 ); + } + lua_pushcfunction( L, embedded_lua_loader ); + lua_rawseti( L, -2, 2 ); + lua_pop( L, 2 ); /* Pop loaders/searchers and package */ + + /* Load from embedded data */ + if ( luaL_loadbuffer( L, (const char*)embedded_main_lua, embedded_main_lua_len, "main.lua" ) != 0 ) { + TraceLog( LOG_ERROR, "Lua error loading embedded main.lua: %s\n", lua_tostring( L, -1 ) ); + return false; + } + if ( lua_pcall( L, 0, 0, 0 ) != 0 ) { + TraceLog( LOG_ERROR, "Lua error executing embedded main.lua: %s\n", lua_tostring( L, -1 ) ); + return false; + } +#else /* If web, set path to resources folder. */ #ifdef PLATFORM_WEB snprintf( path, STRING_LEN, "main.lua" ); @@ -1467,17 +1668,16 @@ void luaCallMain() { #endif if ( !FileExists( path ) ) { TraceLog( LOG_ERROR, "Cannot find file: %s\n", path ); - state->run = false; - return; + return false; } luaL_dofile( L, path ); /* Check errors in main.lua */ if ( lua_tostring( L, -1 ) ) { TraceLog( LOG_ERROR, "Lua error: %s\n", lua_tostring( L, -1 ) ); - state->run = false; - return; + return false; } +#endif lua_pushcfunction( L, luaTraceback ); int tracebackidx = lua_gettop( L ); /* Apply custom callback here. */ @@ -1489,8 +1689,7 @@ void luaCallMain() { if ( lua_isfunction( L, -1 ) ) { if ( lua_pcall( L, 0, 0, tracebackidx ) != 0 ) { TraceLog( LOG_ERROR, "Lua error: %s", lua_tostring( L, -1 ) ); - state->run = false; - return; + return false; } } lua_pop( L, -1 ); @@ -1502,8 +1701,25 @@ void luaCallMain() { stateContextInit(); } else { - state->run = false; + return false; } + + lua_getglobal( L, "RL" ); + lua_getfield( L, -1, "init" ); + + if ( lua_isfunction( L, -1 ) ) { + if ( lua_pcall( L, 0, 0, tracebackidx ) != 0 ) { + TraceLog( LOG_ERROR, "Lua error: %s", lua_tostring( L, -1 ) ); + return false; + } + } + else { + TraceLog( LOG_ERROR, "%s", "No Lua init found!" ); + return false; + } + lua_pop( L, -1 ); + + return state->run; } void luaCallInit() { @@ -1789,6 +2005,10 @@ void luaRegister() { assingGlobalFunction( "GetPrevDirectoryPath", lcoreGetPrevDirectoryPath ); assingGlobalFunction( "GetWorkingDirectory", lcoreGetWorkingDirectory ); assingGlobalFunction( "GetApplicationDirectory", lcoreGetApplicationDirectory ); + /* Asset loading functions. */ + assingGlobalFunction( "BeginAssetLoading", lcoreBeginAssetLoading ); + assingGlobalFunction( "UpdateAssetLoading", lcoreUpdateAssetLoading ); + assingGlobalFunction( "EndAssetLoading", lcoreEndAssetLoading ); assingGlobalFunction( "MakeDirectory", lcoreMakeDirectory ); assingGlobalFunction( "ChangeDirectory", lcoreChangeDirectory ); assingGlobalFunction( "IsPathFile", lcoreIsPathFile ); @@ -1,6 +1,15 @@ #include "main.h" #include "state.h" #include "lua_core.h" +#include "splash.h" + +#ifdef _WIN32 +// Forward declarations for Windows console functions +extern __declspec(dllimport) int __stdcall AllocConsole(void); +extern __declspec(dllimport) int __stdcall FreeConsole(void); +extern __declspec(dllimport) void* __stdcall GetStdHandle(unsigned long nStdHandle); +extern __declspec(dllimport) int __stdcall SetStdHandle(unsigned long nStdHandle, void* hHandle); +#endif static inline void printVersion() { if ( VERSION_DEV ) { @@ -22,30 +31,92 @@ static inline void printVersion() { int main( int argn, const char** argc ) { char basePath[ STRING_LEN ] = { '\0' }; bool interpret_mode = false; + bool show_console = false; + bool skip_splash = false; + +#ifdef _WIN32 + /* Check for --log and --no-logo arguments */ + for ( int i = 1; i < argn; i++ ) { + if ( strcmp( argc[i], "--log" ) == 0 ) { + show_console = true; + } + if ( strcmp( argc[i], "--no-logo" ) == 0 ) { + skip_splash = true; + } + } + + /* Show or hide console based on --log argument */ + if ( show_console ) { + /* Allocate a console if we don't have one */ + if ( AllocConsole() ) { + freopen( "CONOUT$", "w", stdout ); + freopen( "CONOUT$", "w", stderr ); + freopen( "CONIN$", "r", stdin ); + } + } + else { + /* Hide console window */ + FreeConsole(); + } +#else + /* Check for --no-logo on non-Windows platforms */ + for ( int i = 1; i < argn; i++ ) { + if ( strcmp( argc[i], "--no-logo" ) == 0 ) { + skip_splash = true; + break; + } + } +#endif if ( 1 < argn ) { - if ( strcmp( argc[1], "--version" ) == 0 || strcmp( argc[1], "-v" ) == 0 ) { + /* Skip --log and --no-logo flags to find the actual command */ + int arg_index = 1; + while ( arg_index < argn && ( strcmp( argc[arg_index], "--log" ) == 0 || strcmp( argc[arg_index], "--no-logo" ) == 0 ) ) { + arg_index++; + } + + if ( arg_index < argn && ( strcmp( argc[arg_index], "--version" ) == 0 || strcmp( argc[arg_index], "-v" ) == 0 ) ) { printVersion(); return 1; } - else if ( strcmp( argc[1], "--help" ) == 0 || strcmp( argc[1], "-h" ) == 0 ) { - printf( "Usage: ReiLua [Options] [Directory to main.lua or main]\nOptions:\n-h --help\tThis help\n-v --version\tShow ReiLua version\n-i --interpret\tInterpret mode [File name]\n" ); + else if ( arg_index < argn && ( strcmp( argc[arg_index], "--help" ) == 0 || strcmp( argc[arg_index], "-h" ) == 0 ) ) { + printf( "Usage: ReiLua [Options] [Directory to main.lua or main]\nOptions:\n-h --help\tThis help\n-v --version\tShow ReiLua version\n-i --interpret\tInterpret mode [File name]\n--log\t\tShow console for logging\n--no-logo\tSkip splash screens (development)\n" ); return 1; } - else if ( strcmp( argc[1], "--interpret" ) == 0 || strcmp( argc[1], "-i" ) == 0 ) { + else if ( arg_index < argn && ( strcmp( argc[arg_index], "--interpret" ) == 0 || strcmp( argc[arg_index], "-i" ) == 0 ) ) { interpret_mode = true; - if ( 2 < argn ) { - sprintf( basePath, "%s/%s", GetWorkingDirectory(), argc[2] ); + if ( arg_index + 1 < argn ) { + sprintf( basePath, "%s/%s", GetWorkingDirectory(), argc[arg_index + 1] ); } } - else{ - sprintf( basePath, "%s/%s", GetWorkingDirectory(), argc[1] ); + else if ( arg_index < argn ) { + sprintf( basePath, "%s/%s", GetWorkingDirectory(), argc[arg_index] ); + } + else { + /* Only flags were provided, use default path search */ + char testPath[ STRING_LEN ] = { '\0' }; + sprintf( testPath, "%s/main.lua", GetWorkingDirectory() ); + + if ( FileExists( testPath ) ) { + sprintf( basePath, "%s", GetWorkingDirectory() ); + } + else { + sprintf( basePath, "%s", GetApplicationDirectory() ); + } } } - /* If no argument given, assume main.lua is in exe directory. */ + /* If no argument given, check current directory first, then exe directory. */ else { - sprintf( basePath, "%s", GetApplicationDirectory() ); + char testPath[ STRING_LEN ] = { '\0' }; + sprintf( testPath, "%s/main.lua", GetWorkingDirectory() ); + + if ( FileExists( testPath ) ) { + sprintf( basePath, "%s", GetWorkingDirectory() ); + } + else { + sprintf( basePath, "%s", GetApplicationDirectory() ); + } } if ( interpret_mode ) { @@ -65,15 +136,30 @@ int main( int argn, const char** argc ) { else { printVersion(); stateInit( argn, argc, basePath ); - luaCallMain(); - luaCallInit(); + + /* Show splash screens if not skipped */ + if ( !skip_splash ) { + splashInit(); + bool splashDone = false; + + while ( !splashDone && !WindowShouldClose() ) { + float delta = GetFrameTime(); + splashDone = splashUpdate( delta ); + splashDraw(); + } + + splashCleanup(); + } + + /* Now run the main Lua program */ + state->run = luaCallMain(); while ( state->run ) { - luaCallUpdate(); - luaCallDraw(); if ( WindowShouldClose() ) { state->run = false; } + luaCallUpdate(); + luaCallDraw(); } luaCallExit(); } diff --git a/src/splash.c b/src/splash.c new file mode 100644 index 0000000..185db0c --- /dev/null +++ b/src/splash.c @@ -0,0 +1,198 @@ +#include "main.h" +#include "state.h" +#include "splash.h" + +#ifdef EMBED_LOGO + #include "embedded_logo.h" +#endif + +#define FADE_IN_TIME 0.8f +#define DISPLAY_TIME 2.5f +#define FADE_OUT_TIME 0.8f +#define SPLASH_TOTAL_TIME (FADE_IN_TIME + DISPLAY_TIME + FADE_OUT_TIME) + +typedef enum { + SPLASH_INDRAJITH, + SPLASH_MADE_WITH, + SPLASH_DONE +} SplashState; + +static SplashState currentSplash = SPLASH_INDRAJITH; +static float splashTimer = 0.0f; +static Texture2D raylibLogo = { 0 }; +static Texture2D reiluaLogo = { 0 }; +static bool logosLoaded = false; + +static float getSplashAlpha( float timer ) { + if ( timer < FADE_IN_TIME ) { + return timer / FADE_IN_TIME; + } + else if ( timer < FADE_IN_TIME + DISPLAY_TIME ) { + return 1.0f; + } + else { + float fadeOut = timer - FADE_IN_TIME - DISPLAY_TIME; + return 1.0f - ( fadeOut / FADE_OUT_TIME ); + } +} + +static void loadSplashLogos() { + if ( logosLoaded ) return; + +#ifdef EMBED_LOGO + /* Load from embedded data */ + Image raylib_img = LoadImageFromMemory( ".png", embedded_raylib_logo, embedded_raylib_logo_size ); + raylibLogo = LoadTextureFromImage( raylib_img ); + UnloadImage( raylib_img ); + + Image reilua_img = LoadImageFromMemory( ".png", embedded_reilua_logo, embedded_reilua_logo_size ); + reiluaLogo = LoadTextureFromImage( reilua_img ); + UnloadImage( reilua_img ); +#else + /* Load from files (development mode) */ + if ( FileExists( "logo/raylib_logo.png" ) ) { + raylibLogo = LoadTexture( "logo/raylib_logo.png" ); + } + if ( FileExists( "logo/reilua_logo.png" ) ) { + reiluaLogo = LoadTexture( "logo/reilua_logo.png" ); + } +#endif + + logosLoaded = true; +} + +static void unloadSplashLogos() { + if ( !logosLoaded ) return; + + UnloadTexture( raylibLogo ); + UnloadTexture( reiluaLogo ); + logosLoaded = false; +} + +static void drawIndrajithSplash( float alpha ) { + int screenWidth = GetScreenWidth(); + int screenHeight = GetScreenHeight(); + + ClearBackground( (Color){ 230, 41, 55, 255 } ); // Raylib red + + const char* text = "INDRAJITH MAKES GAMES"; + int fontSize = 48; + float spacing = 2.0f; + + Color textColor = WHITE; + textColor.a = (unsigned char)(255 * alpha); + + /* Draw text with slight expansion effect during fade in */ + float scale = 0.95f + (alpha * 0.05f); // Subtle scale from 0.95 to 1.0 + + /* Measure text with proper spacing for accurate centering */ + Vector2 textSize = MeasureTextEx( state->defaultFont, text, fontSize * scale, spacing ); + + /* Calculate centered position */ + Vector2 position = { + (float)(screenWidth / 2) - (textSize.x / 2), + (float)(screenHeight / 2) - (textSize.y / 2) + }; + + /* Draw with proper kerning */ + DrawTextEx( state->defaultFont, text, position, fontSize * scale, spacing, textColor ); +} + +static void drawMadeWithSplash( float alpha ) { + int screenWidth = GetScreenWidth(); + int screenHeight = GetScreenHeight(); + + ClearBackground( BLACK ); + + /* "Made using" text at top */ + const char* madeText = "Made using"; + int madeSize = 32; + int madeWidth = MeasureText( madeText, madeSize ); + + Color textColor = WHITE; + textColor.a = (unsigned char)(255 * alpha); + + int textY = screenHeight / 2 - 100; + DrawText( madeText, screenWidth / 2 - madeWidth / 2, textY, madeSize, textColor ); + + /* Calculate logo sizes and positions - scale down if too large */ + int maxLogoSize = 200; + float raylibScale = 1.0f; + float reiluaScale = 1.0f; + + if ( raylibLogo.id > 0 && raylibLogo.width > maxLogoSize ) { + raylibScale = (float)maxLogoSize / (float)raylibLogo.width; + } + if ( reiluaLogo.id > 0 && reiluaLogo.width > maxLogoSize ) { + reiluaScale = (float)maxLogoSize / (float)reiluaLogo.width; + } + + int raylibWidth = (int)(raylibLogo.width * raylibScale); + int raylibHeight = (int)(raylibLogo.height * raylibScale); + int reiluaWidth = (int)(reiluaLogo.width * reiluaScale); + int reiluaHeight = (int)(reiluaLogo.height * reiluaScale); + + /* Position logos side by side with spacing */ + int spacing = 40; + int totalWidth = raylibWidth + spacing + reiluaWidth; + int startX = screenWidth / 2 - totalWidth / 2; + int logoY = screenHeight / 2 - 20; + + Color tint = WHITE; + tint.a = (unsigned char)(255 * alpha); + + /* Draw Raylib logo */ + if ( raylibLogo.id > 0 ) { + Rectangle source = { 0, 0, (float)raylibLogo.width, (float)raylibLogo.height }; + Rectangle dest = { (float)startX, (float)logoY, (float)raylibWidth, (float)raylibHeight }; + DrawTexturePro( raylibLogo, source, dest, (Vector2){ 0, 0 }, 0.0f, tint ); + } + + /* Draw ReiLua logo */ + if ( reiluaLogo.id > 0 ) { + int reiluaX = startX + raylibWidth + spacing; + Rectangle source = { 0, 0, (float)reiluaLogo.width, (float)reiluaLogo.height }; + Rectangle dest = { (float)reiluaX, (float)logoY, (float)reiluaWidth, (float)reiluaHeight }; + DrawTexturePro( reiluaLogo, source, dest, (Vector2){ 0, 0 }, 0.0f, tint ); + } +} + +void splashInit() { + loadSplashLogos(); + currentSplash = SPLASH_INDRAJITH; + splashTimer = 0.0f; +} + +bool splashUpdate( float delta ) { + splashTimer += delta; + + if ( splashTimer >= SPLASH_TOTAL_TIME ) { + splashTimer = 0.0f; + currentSplash++; + } + + return currentSplash >= SPLASH_DONE; +} + +void splashDraw() { + float alpha = getSplashAlpha( splashTimer ); + + BeginDrawing(); + + switch ( currentSplash ) { + case SPLASH_INDRAJITH: + drawIndrajithSplash( alpha ); + break; + case SPLASH_MADE_WITH: + drawMadeWithSplash( alpha ); + break; + default: + break; + } + + EndDrawing(); +} + +void splashCleanup() { + unloadSplashLogos(); +} |
