diff options
| author | Indrajith K L | 2025-11-10 01:58:00 +0530 |
|---|---|---|
| committer | Indrajith K L | 2025-11-10 01:58:25 +0530 |
| commit | d9d1a8a51ea7cd7e7076724918008b6adb1302ca (patch) | |
| tree | 59a8f258c9bb4db4edafc2c70993319e3c3c859c | |
| parent | 8c9367f3689aee05d33fc1cae8a5d1aa6d2b5fb8 (diff) | |
| download | reilua-enhanced-d9d1a8a51ea7cd7e7076724918008b6adb1302ca.tar.gz reilua-enhanced-d9d1a8a51ea7cd7e7076724918008b6adb1302ca.tar.bz2 reilua-enhanced-d9d1a8a51ea7cd7e7076724918008b6adb1302ca.zip | |
Add flexible module loading and complete file embedding
- Support any folder structure (no hard-coded folders)
- Embed all file types recursively from any folder
- Fix require() dot-to-slash conversion for embedded modules
- Clean build folder for fresh builds every time
- Generate empty headers for Lua-only projects
Backward compatible with existing projects.
| -rw-r--r-- | CMakeLists.txt | 55 | ||||
| -rw-r--r-- | scripts/build_dev.bat | 54 | ||||
| -rwxr-xr-x | scripts/build_dev.sh | 46 | ||||
| -rw-r--r-- | scripts/build_release.bat | 69 | ||||
| -rwxr-xr-x | scripts/build_release.sh | 96 | ||||
| -rw-r--r-- | scripts/create_empty_assets.py | 24 | ||||
| -rw-r--r-- | scripts/embed_assets.py | 40 | ||||
| -rw-r--r-- | scripts/embed_lua.py | 40 | ||||
| -rw-r--r-- | src/lua_core.c | 65 |
9 files changed, 283 insertions, 206 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index aef831d..603c8f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,15 +97,15 @@ if( WIN32 ) list( APPEND SOURCES ${CMAKE_SOURCE_DIR}/resources.rc ) endif() -# Embed Lua files if EMBED_MAIN is ON +# Embed Lua files if EMBED_MAIN is ON (recursively from all subdirectories) if( EMBED_MAIN ) - file( GLOB LUA_FILES "${CMAKE_CURRENT_BINARY_DIR}/*.lua" ) + file( GLOB_RECURSE LUA_FILES "${CMAKE_CURRENT_BINARY_DIR}/*.lua" ) if( LUA_FILES ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/embed_lua.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h ${LUA_FILES} DEPENDS ${LUA_FILES} - COMMENT "Embedding Lua files into executable..." + COMMENT "Embedding Lua files from all subdirectories into executable..." ) list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_main.h ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_MAIN" ) @@ -114,21 +114,60 @@ if( EMBED_MAIN ) endif() endif() -# Embed asset files if EMBED_ASSETS is ON +# Embed all non-Lua data files if EMBED_ASSETS is ON (from all subdirectories except CMake dirs) +# Always create embedded_assets.h to prevent compilation errors if( EMBED_ASSETS ) - file( GLOB_RECURSE ASSET_FILES "${CMAKE_CURRENT_BINARY_DIR}/assets/*" ) + # Find all non-Lua files recursively, excluding build system files + file( GLOB_RECURSE ALL_DATA_FILES + "${CMAKE_CURRENT_BINARY_DIR}/*" + ) + # Filter out unwanted files + set( ASSET_FILES "" ) + foreach( FILE_PATH ${ALL_DATA_FILES} ) + # Exclude: .lua files (handled separately), build artifacts, and CMake files + if( NOT FILE_PATH MATCHES "\\.lua$" + AND NOT FILE_PATH MATCHES "CMakeFiles" + AND NOT FILE_PATH MATCHES "\\.cmake$" + AND NOT FILE_PATH MATCHES "CMakeCache" + AND NOT FILE_PATH MATCHES "Makefile$" + AND NOT FILE_PATH MATCHES "\\.a$" + AND NOT FILE_PATH MATCHES "\\.o$" + AND NOT FILE_PATH MATCHES "embedded_.*\\.h$" + AND NOT FILE_PATH MATCHES "\\.exe$" + AND NOT FILE_PATH MATCHES "ReiLua$" ) + list( APPEND ASSET_FILES ${FILE_PATH} ) + endif() + endforeach() + if( ASSET_FILES ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/embed_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h ${ASSET_FILES} DEPENDS ${ASSET_FILES} - COMMENT "Embedding asset files into executable..." + COMMENT "Embedding data files from all subdirectories into executable..." ) - list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h ) set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" ) + message( STATUS "Embedding ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h with asset files" ) else() - message( WARNING "EMBED_ASSETS is ON but no files found in build/assets/ directory!" ) + # Create empty embedded_assets.h to prevent compilation errors + message( STATUS "EMBED_ASSETS is ON but no data files found, creating empty embedded_assets.h" ) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/create_empty_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h + COMMENT "Creating empty embedded_assets.h (no data files to embed)" + ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DEMBED_ASSETS" ) endif() + list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h ) +else() + # EMBED_ASSETS is OFF - create empty header for compatibility + message( STATUS "EMBED_ASSETS is OFF, creating empty embedded_assets.h" ) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h + COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/scripts/create_empty_assets.py ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h + COMMENT "Creating empty embedded_assets.h (EMBED_ASSETS is OFF)" + ) + list( APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/embedded_assets.h ) endif() add_executable( ${PROJECT_NAME} ${SOURCES} ) diff --git a/scripts/build_dev.bat b/scripts/build_dev.bat index 40f394e..a1995d6 100644 --- a/scripts/build_dev.bat +++ b/scripts/build_dev.bat @@ -18,60 +18,25 @@ if errorlevel 1 ( exit /b 1 ) -REM Clean old embedded files (important for dev builds!) -echo Cleaning old embedded files... -del /Q embedded_main.h embedded_assets.h 2>nul - -REM Warn about Lua files in build directory -dir /b *.lua >nul 2>&1 -if not errorlevel 1 ( - echo. - echo WARNING: Found Lua files in build directory! - echo Development builds should load from file system, not embed. - echo. - dir /b *.lua - echo. - set /p REMOVE="Remove these files from build directory? (Y/n): " - if /i not "%REMOVE%"=="n" ( - del /Q *.lua - echo Lua files removed. - ) - echo. -) - -REM Warn about assets folder in build directory -if exist "assets" ( - echo. - echo WARNING: Found assets folder in build directory! - echo Development builds should load from file system, not embed. - echo. - set /p REMOVE="Remove assets folder from build directory? (Y/n): " - if /i not "%REMOVE%"=="n" ( - rmdir /S /Q assets - echo Assets folder removed. - ) - echo. -) - -REM Clean old configuration if requested -if "%1"=="clean" ( - echo Cleaning build directory... - del /Q CMakeCache.txt *.o *.a 2>nul - rmdir /S /Q CMakeFiles 2>nul - echo Clean complete! - echo. -) +REM ALWAYS clean build folder for fresh build +echo Cleaning build directory for fresh build... +del /Q /S * >nul 2>&1 +for /d %%p in (*) do rmdir "%%p" /s /q >nul 2>&1 +echo * Build directory cleaned +echo. -REM Configure with MinGW +REM Configure echo Configuring CMake for development... cmake -G "MinGW Makefiles" .. if errorlevel 1 ( echo. echo ERROR: CMake configuration failed! + pause exit /b 1 ) +REM Build echo. echo Building ReiLua... mingw32-make @@ -79,6 +44,7 @@ mingw32-make if errorlevel 1 ( echo. echo ERROR: Build failed! + pause exit /b 1 ) diff --git a/scripts/build_dev.sh b/scripts/build_dev.sh index 5912bb0..914df21 100755 --- a/scripts/build_dev.sh +++ b/scripts/build_dev.sh @@ -62,49 +62,15 @@ fi mkdir -p build cd build || exit 1 -# Clean old embedded files (important for dev builds!) -echo "Cleaning old embedded files..." -rm -f embedded_main.h embedded_assets.h - -# Warn about Lua files in build directory -LUA_COUNT=$(ls *.lua 2>/dev/null | wc -l) -if [ "$LUA_COUNT" -gt 0 ]; then - echo "" - echo "WARNING: Found Lua files in build directory!" - echo "Development builds should load from file system, not embed." - echo "" - ls -1 *.lua - echo "" - read -p "Remove these files from build directory? (Y/n): " -n 1 -r - echo "" - if [[ ! $REPLY =~ ^[Nn]$ ]]; then - rm -f *.lua - echo "Lua files removed." - fi - echo "" -fi - -# Warn about assets folder in build directory -if [ -d "assets" ]; then - echo "" - echo "WARNING: Found assets folder in build directory!" - echo "Development builds should load from file system, not embed." - echo "" - read -p "Remove assets folder from build directory? (Y/n): " -n 1 -r - echo "" - if [[ ! $REPLY =~ ^[Nn]$ ]]; then - rm -rf assets - echo "Assets folder removed." - fi - echo "" -fi +# ALWAYS clean build folder for fresh build +echo "Cleaning build directory for fresh build..." +rm -rf ./* 2>/dev/null +echo "✓ Build directory cleaned" +echo "" # Clean old configuration if requested if [ "$1" == "clean" ]; then - echo "Cleaning build directory..." - rm -rf CMakeCache.txt CMakeFiles/ *.o *.a - echo "Clean complete!" - echo "" + echo "Extra clean flag detected (already cleaned)" fi # Detect platform and set appropriate generator diff --git a/scripts/build_release.bat b/scripts/build_release.bat index a1a08c0..4f9ce43 100644 --- a/scripts/build_release.bat +++ b/scripts/build_release.bat @@ -24,21 +24,48 @@ if errorlevel 1 ( exit /b 1 ) +REM ALWAYS clean build folder for fresh build +echo Cleaning build directory for fresh build... +del /Q /S * >nul 2>&1 +for /d %%p in (*) do rmdir "%%p" /s /q >nul 2>&1 +echo * Build directory cleaned +echo. + REM Clean old embedded files -echo Cleaning old embedded files... +echo Ready for fresh build... del /Q embedded_main.h embedded_assets.h 2>nul -REM Check for Lua files +REM Auto-copy from game folder if it exists echo. +if exist "..\game" ( + echo Found game/ folder - auto-copying ALL contents to build... + + REM Copy all files from game folder recursively, excluding LSP files + xcopy /E /I /Y /EXCLUDE:..\game\ReiLua_API.lua+..\game\.luarc.json "..\game\*" . >nul 2>&1 + if exist "..\game\ReiLua_API.lua" del /Q "ReiLua_API.lua" 2>nul + if exist "..\game\.luarc.json" del /Q ".luarc.json" 2>nul + + echo * Copied ALL game files and folders + echo * All folder structures preserved ^(user-created folders included^) + echo. +) + +REM Check for Lua files echo Checking for Lua files... dir /b *.lua >nul 2>&1 if errorlevel 1 ( echo. echo WARNING: No Lua files found in build directory! echo. - echo Please copy your Lua files: - echo cd build - echo copy ..\your_game\*.lua . + if exist "..\game" ( + echo No Lua files found in game/ folder. + echo Add your main.lua to game/ folder and try again. + ) else ( + echo Tip: Create a game/ folder in project root and add main.lua there. + echo Or manually copy files: + echo cd build + echo copy ..\your_game\*.lua . + ) echo. set /p CONTINUE="Do you want to continue anyway? (y/N): " if /i not "%CONTINUE%"=="y" exit /b 1 @@ -47,24 +74,22 @@ if errorlevel 1 ( dir /b *.lua ) -REM Check for assets folder +REM Check for non-Lua data files (any folder, any file type) echo. -echo Checking for assets... -if not exist "assets" ( - echo. - echo WARNING: No assets folder found! - echo. - echo To embed assets, create the folder and copy files: - echo cd build - echo mkdir assets - echo copy ..\your_game\assets\* assets\ - echo. - set /p CONTINUE="Do you want to continue without assets? (y/N): " - if /i not "%CONTINUE%"=="y" exit /b 1 - set EMBED_ASSETS=OFF -) else ( - echo Found assets folder +echo Checking for data files to embed... +set DATA_COUNT=0 +for /r %%f in (*) do ( + echo %%~nxf | findstr /i /v ".lua .exe .o .a CMake Makefile" >nul + if not errorlevel 1 set /a DATA_COUNT+=1 +) + +if %DATA_COUNT% GTR 0 ( + echo Found data files to embed + echo ^(includes: images, sounds, config, data, and any other files^) set EMBED_ASSETS=ON +) else ( + echo No non-Lua files found ^(only Lua code will be embedded^) + set EMBED_ASSETS=OFF ) echo. @@ -72,7 +97,7 @@ echo ================================ echo Build Configuration echo ================================ echo Lua Embedding: ON -echo Asset Embedding: %EMBED_ASSETS% +echo Data Embedding: %EMBED_ASSETS% echo Build Type: Release echo ================================ echo. diff --git a/scripts/build_release.sh b/scripts/build_release.sh index 5c0e6ab..6f2c0f7 100755 --- a/scripts/build_release.sh +++ b/scripts/build_release.sh @@ -68,38 +68,50 @@ fi mkdir -p build cd build || exit 1 +# ALWAYS clean build folder for fresh build +echo "Cleaning build directory for fresh build..." +rm -rf ./* 2>/dev/null +echo "✓ Build directory cleaned" +echo "" + # Clean old embedded files -echo "Cleaning old embedded files..." -rm -f embedded_main.h embedded_assets.h +echo "Ready for fresh build..." +rm -f embedded_main.h embedded_assets.h 2>/dev/null # Auto-copy from game folder if it exists echo "" if [ -d "../game" ]; then - echo "Found game/ folder - auto-copying contents to build..." + echo "Found game/ folder - auto-copying ALL contents to build..." - # Copy all Lua files from game folder EXCEPT ReiLua_API.lua - if ls ../game/*.lua 1> /dev/null 2>&1; then - for lua_file in ../game/*.lua; do - filename=$(basename "$lua_file") - if [ "$filename" != "ReiLua_API.lua" ]; then - cp "$lua_file" . - fi - done - LUA_COUNT=$(ls *.lua 2>/dev/null | wc -l) - echo " ✓ Copied $LUA_COUNT Lua file(s)" - else - echo " ⚠ No Lua files found in game/" - fi + # Copy everything from game folder recursively, excluding: + # - ReiLua_API.lua (LSP only) + # - .luarc.json (LSP config) + # - .DS_Store (macOS) + # - Hidden files starting with . (except .gitkeep if present) - # Copy assets folder if it exists - if [ -d "../game/assets" ]; then - rm -rf assets - cp -r ../game/assets . - ASSET_COUNT=$(find assets -type f 2>/dev/null | wc -l) - echo " ✓ Copied assets/ ($ASSET_COUNT files)" + # Use rsync if available for better copying, otherwise use cp + if command -v rsync &> /dev/null; then + rsync -av --exclude='ReiLua_API.lua' --exclude='.luarc.json' --exclude='.DS_Store' --exclude='.*' --include='.gitkeep' ../game/ . 2>/dev/null else - echo " ℹ No assets folder in game/" + # Fallback to find + cp - Copy ALL files and directories + (cd ../game && find . -type f \ + ! -name 'ReiLua_API.lua' \ + ! -name '.luarc.json' \ + ! -name '.DS_Store' \ + ! -path '*/\.*' -o -name '.gitkeep' \ + -exec sh -c 'mkdir -p "../build/$(dirname "{}")" && cp -p "{}" "../build/{}"' \; 2>/dev/null) fi + + # Count what was copied + LUA_COUNT=$(find . -maxdepth 10 -name "*.lua" -type f 2>/dev/null | wc -l) + ASSET_COUNT=$(find assets -type f 2>/dev/null | wc -l || echo "0") + TOTAL_FILES=$(find . -type f ! -path './CMakeFiles/*' ! -path './.cmake/*' ! -name 'CMake*' ! -name '*.a' ! -name '*.o' 2>/dev/null | wc -l) + + echo " ✓ Copied ALL game files and folders:" + echo " - $LUA_COUNT Lua file(s) (including all subdirectories)" + echo " - $ASSET_COUNT Asset file(s) (if assets folder exists)" + echo " - $TOTAL_FILES total file(s)" + echo " - All folder structures preserved (user-created folders included)" echo "" fi @@ -131,34 +143,18 @@ else ls -1 *.lua fi -# Check for assets folder +# Check for non-Lua data files (any folder, any file type) echo "" -echo "Checking for assets..." -if [ ! -d "assets" ]; then - echo "" - echo "WARNING: No assets folder found!" - echo "" - if [ -d "../game" ]; then - echo "No assets found in game/assets/ folder." - echo "Add assets to game/assets/ if you need them embedded." - else - echo "Tip: Create game/assets/ in project root for auto-copy." - echo "Or manually:" - echo " cd build" - echo " mkdir assets" - echo " cp ../your_game/assets/* assets/" - fi - echo "" - read -p "Do you want to continue without assets? (y/N): " -n 1 -r - echo "" - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi - EMBED_ASSETS="OFF" -else - ASSET_FILES=$(find assets -type f 2>/dev/null | wc -l) - echo "Found $ASSET_FILES asset file(s) in assets folder" +echo "Checking for data files to embed..." +NON_LUA_FILES=$(find . -type f ! -name "*.lua" ! -path "./CMakeFiles/*" ! -path "./.cmake/*" ! -name "CMake*" ! -name "Makefile*" ! -name "*.o" ! -name "*.a" 2>/dev/null | wc -l) + +if [ "$NON_LUA_FILES" -gt 0 ]; then + echo "Found $NON_LUA_FILES non-Lua file(s) to embed" + echo " (includes: images, sounds, config, data, and any other files)" EMBED_ASSETS="ON" +else + echo "No non-Lua files found (only Lua code will be embedded)" + EMBED_ASSETS="OFF" fi echo "" @@ -166,7 +162,7 @@ echo "================================" echo "Build Configuration" echo "================================" echo "Lua Embedding: ON" -echo "Asset Embedding: $EMBED_ASSETS" +echo "Data Embedding: $EMBED_ASSETS" echo "Build Type: Release" echo "================================" echo "" diff --git a/scripts/create_empty_assets.py b/scripts/create_empty_assets.py new file mode 100644 index 0000000..fbc2d11 --- /dev/null +++ b/scripts/create_empty_assets.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +""" +Create an empty embedded_assets.h file for compatibility. +Usage: python create_empty_assets.py <output.h> +""" +import sys + +if __name__ == '__main__': + if len(sys.argv) < 2: + print('Usage: python create_empty_assets.py <output.h>') + sys.exit(1) + + output_file = sys.argv[1] + + with open(output_file, 'w') as f: + f.write('#ifndef EMBEDDED_ASSETS_H\n') + f.write('#define EMBEDDED_ASSETS_H\n') + f.write('/* No assets to embed */\n') + f.write('typedef struct { const char* name; const unsigned char* data; unsigned int size; } EmbeddedAsset;\n') + f.write('static const EmbeddedAsset embedded_assets[] = {};\n') + f.write('static const int embedded_asset_count = 0;\n') + f.write('#endif\n') + + print(f'Created empty {output_file}') diff --git a/scripts/embed_assets.py b/scripts/embed_assets.py index 52309ef..df4489a 100644 --- a/scripts/embed_assets.py +++ b/scripts/embed_assets.py @@ -40,17 +40,18 @@ def embed_files(output_file, input_files): data = inf.read() var_name = sanitize_name(input_file) - # Extract relative path from 'assets/' onwards if present - if 'assets' in input_file.replace('\\', '/'): - parts = input_file.replace('\\', '/').split('assets/') - if len(parts) > 1: - relative_name = 'assets/' + parts[-1] - else: - relative_name = os.path.basename(input_file) - else: - relative_name = os.path.basename(input_file) + # Extract relative path from build directory + relative_name = input_file + for prefix in ['build/', 'build\\']: + if prefix in input_file: + parts = input_file.split(prefix, 1) + if len(parts) > 1: + relative_name = parts[1] + break + # Normalize path separators + relative_name = relative_name.replace('\\', '/') - f.write(f'/* Embedded asset: {input_file} ({len(data)} bytes) */\n') + f.write(f'/* Embedded file: {relative_name} ({len(data)} bytes) */\n') f.write(f'static const unsigned char embedded_asset_{idx}_{var_name}[] = {{\n') for i, byte in enumerate(data): @@ -78,15 +79,16 @@ def embed_files(output_file, input_files): f.write('static const EmbeddedAsset embedded_assets[] = {\n') for idx, input_file in enumerate(input_files): var_name = sanitize_name(input_file) - # Extract relative path from 'assets/' onwards if present - if 'assets' in input_file.replace('\\', '/'): - parts = input_file.replace('\\', '/').split('assets/') - if len(parts) > 1: - relative_name = 'assets/' + parts[-1] - else: - relative_name = os.path.basename(input_file) - else: - relative_name = os.path.basename(input_file) + # Extract relative path from build directory + relative_name = input_file + for prefix in ['build/', 'build\\']: + if prefix in input_file: + parts = input_file.split(prefix, 1) + if len(parts) > 1: + relative_name = parts[1] + break + # Normalize path separators + relative_name = relative_name.replace('\\', '/') f.write(f' {{ "{relative_name}", embedded_asset_{idx}_{var_name}, embedded_asset_{idx}_{var_name}_len }},\n') f.write('};\n\n') diff --git a/scripts/embed_lua.py b/scripts/embed_lua.py index 9562354..0d20921 100644 --- a/scripts/embed_lua.py +++ b/scripts/embed_lua.py @@ -27,7 +27,17 @@ def embed_files(output_file, input_files): data = inf.read() var_name = sanitize_name(input_file) - f.write(f'/* Embedded file: {input_file} */\n') + # Get relative path for better module loading + # Try to extract path relative to common directories + relative_name = input_file + for prefix in ['build/', 'build\\']: + if prefix in input_file: + parts = input_file.split(prefix, 1) + if len(parts) > 1: + relative_name = parts[1] + break + + f.write(f'/* Embedded file: {relative_name} */\n') f.write(f'static const unsigned char embedded_lua_{idx}_{var_name}[] = {{\n') for i, byte in enumerate(data): @@ -55,18 +65,32 @@ def embed_files(output_file, input_files): f.write('static const EmbeddedLuaFile embedded_lua_files[] = {\n') for idx, input_file in enumerate(input_files): var_name = sanitize_name(input_file) - # Store both original filename and basename for require compatibility - basename = os.path.basename(input_file) - f.write(f' {{ "{basename}", embedded_lua_{idx}_{var_name}, embedded_lua_{idx}_{var_name}_len }},\n') + # Store relative path for proper require() support + relative_name = input_file + for prefix in ['build/', 'build\\']: + if prefix in input_file: + parts = input_file.split(prefix, 1) + if len(parts) > 1: + relative_name = parts[1] + break + # Normalize path separators + relative_name = relative_name.replace('\\', '/') + f.write(f' {{ "{relative_name}", embedded_lua_{idx}_{var_name}, embedded_lua_{idx}_{var_name}_len }},\n') f.write('};\n\n') f.write(f'static const int embedded_lua_file_count = {len(input_files)};\n\n') - # Main entry point (first file) - var_name = sanitize_name(input_files[0]) + # Main entry point (first file with 'main.lua' in name, or first file) + main_idx = 0 + for idx, input_file in enumerate(input_files): + if 'main.lua' in input_file.lower(): + main_idx = idx + break + + var_name = sanitize_name(input_files[main_idx]) f.write('/* Main entry point */\n') - f.write(f'#define embedded_main_lua embedded_lua_0_{var_name}\n') - f.write(f'#define embedded_main_lua_len embedded_lua_0_{var_name}_len\n\n') + f.write(f'#define embedded_main_lua embedded_lua_{main_idx}_{var_name}\n') + f.write(f'#define embedded_main_lua_len embedded_lua_{main_idx}_{var_name}_len\n\n') f.write('#endif /* EMBEDDED_MAIN_H */\n') diff --git a/src/lua_core.c b/src/lua_core.c index 8d4bf52..6f0a6f6 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -124,23 +124,39 @@ 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 ); + /* Convert module name dots to slashes (e.g., "lib.gamestate" -> "lib/gamestate") */ + char converted_name[512]; + strncpy( converted_name, name, sizeof(converted_name) - 1 ); + converted_name[sizeof(converted_name) - 1] = '\0'; + for ( char* p = converted_name; *p; p++ ) { + if ( *p == '.' ) *p = '/'; + } + + /* Try both converted name and original name */ + const char* names_to_try[] = { converted_name, name }; + + for ( int n = 0; n < 2; n++ ) { + const char* try_name = names_to_try[n]; - 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 ) ) { + for ( int i = 0; i < embedded_lua_file_count; i++ ) { + const EmbeddedLuaFile* file = &embedded_lua_files[i]; - 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; + const char* basename = file->name; + size_t name_len = strlen( try_name ); + size_t base_len = strlen( basename ); + + /* Match exactly, or match without .lua extension */ + if ( strcmp( basename, try_name ) == 0 || + ( base_len > 4 && strcmp( basename + base_len - 4, ".lua" ) == 0 && + strncmp( basename, try_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; + } } } } @@ -1530,6 +1546,25 @@ bool luaInit( int argn, const char** argc ) { TraceLog( LOG_WARNING, "%s", "Failed to init Lua" ); return false; } + + /* Configure package.path to include basePath and all subdirectories */ + if ( state->basePath != NULL && strlen( state->basePath ) > 0 ) { + lua_getglobal( L, "package" ); + lua_getfield( L, -1, "path" ); + const char* currentPath = lua_tostring( L, -1 ); + lua_pop( L, 1 ); + + /* Add basePath and recursive subdirectory patterns for flexible module loading */ + char newPath[STRING_LEN * 4]; + snprintf( newPath, sizeof(newPath), + "%s?.lua;%s?/init.lua;%s?/?.lua;%s?/?/init.lua;%s", + state->basePath, state->basePath, state->basePath, state->basePath, currentPath ); + + lua_pushstring( L, newPath ); + lua_setfield( L, -2, "path" ); + lua_pop( L, 1 ); + } + /* Define object types. */ defineBuffer(); defineImage(); |
