Scripts work again.
All checks were successful
Build Dusk / run-tests (push) Successful in 1m40s
Build Dusk / build-linux (push) Successful in 1m45s
Build Dusk / build-psp (push) Successful in 1m47s
Build Dusk / build-dolphin (push) Successful in 2m23s

This commit is contained in:
2026-02-13 19:36:59 -06:00
parent e5e8c49f6c
commit af9904c892
22 changed files with 183 additions and 282 deletions

View File

@@ -30,6 +30,7 @@ set(DUSK_BUILD_BINARY ${DUSK_BUILD_DIR}/Dusk CACHE INTERNAL ${DUSK_CACHE_TARGET}
set(DUSK_ASSETS "" CACHE INTERNAL ${DUSK_CACHE_TARGET})
set(DUSK_LIBRARY_TARGET_NAME "DuskCore" CACHE INTERNAL ${DUSK_CACHE_TARGET})
set(DUSK_BINARY_TARGET_NAME "Dusk" CACHE INTERNAL ${DUSK_CACHE_TARGET})
set(DUSK_ASSETS_ZIP "${DUSK_BUILD_DIR}/dusk.dsk" CACHE INTERNAL ${DUSK_CACHE_TARGET})
# Create directories
file(MAKE_DIRECTORY ${DUSK_GENERATED_HEADERS_DIR})
@@ -176,16 +177,18 @@ if(ENABLE_TESTS)
endif()
# Build assets
# dusk_run_python(
# DUSK_ASSETS_BUILT
# tools.asset.bundle
# --assets ${DUSK_ASSETS_DIR}
# --output-assets ${DUSK_BUILT_ASSETS_DIR}
# --output-file ${DUSK_BUILD_DIR}/dusk.dsk
# --headers-dir ${DUSK_GENERATED_HEADERS_DIR}
# --input ${DUSK_ASSETS}
# )
# add_dependencies(${DUSK_LIBRARY_TARGET_NAME} DUSK_ASSETS_BUILT)
file(GLOB_RECURSE DUSK_ASSET_FILES CONFIGURE_DEPENDS "${DUSK_ASSETS_DIR}/*")
add_custom_command(
OUTPUT "${DUSK_ASSETS_ZIP}"
COMMAND ${CMAKE_COMMAND} -E make_directory "${DUSK_ASSETS_DIR}"
COMMAND ${CMAKE_COMMAND} -E rm -f "${DUSK_ASSETS_ZIP}"
COMMAND ${CMAKE_COMMAND} -E tar "cf" "${DUSK_ASSETS_ZIP}" --format=zip -- .
WORKING_DIRECTORY "${DUSK_ASSETS_DIR}"
DEPENDS ${DUSK_ASSET_FILES}
VERBATIM
)
add_custom_target(DUSK_ASSETS_BUILT DEPENDS "${DUSK_ASSETS_ZIP}")
add_dependencies(${DUSK_LIBRARY_TARGET_NAME} DUSK_ASSETS_BUILT)
# Include generated headers
target_include_directories(${DUSK_LIBRARY_TARGET_NAME} PUBLIC
@@ -200,7 +203,7 @@ if(DUSK_TARGET_SYSTEM STREQUAL "psp")
BACKGROUND_PATH NULL
PREVIEW_PATH NULL
TITLE "${DUSK_BINARY_TARGET_NAME}"
PSAR_PATH ${DUSK_BUILD_DIR}/dusk.dsk
PSAR_PATH ${DUSK_ASSETS_ZIP}
VERSION 01.00
)
elseif(DUSK_TARGET_SYSTEM STREQUAL "gamecube" OR DUSK_TARGET_SYSTEM STREQUAL "wii")

View File

@@ -56,5 +56,4 @@ else
end
end
localeSet(DUSK_LOCALE_EN_US)
sceneSet('scene/minesweeper.dsf')
sceneSet('scene/minesweeper.lua')

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2026 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_asset(TILESET ui.png type=PALETTIZED tileWidth=8 tileHeight=8)
add_asset(TILESET cell.png type=PALETTIZED tileWidth=8 tileHeight=8)
add_asset(TILESET border.png type=PALETTIZED tileWidth=8 tileHeight=8)
add_asset(IMAGE grid_bg.png type=PALETTIZED)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -18,39 +18,39 @@ CELL_STATE_DISABLED = 3
screenSetBackground(colorBlack())
camera = cameraCreate(CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC)
tilesetUi = tilesetGetByName("ui")
textureUi = textureLoad(tilesetUi.texture)
-- tilesetUi = tilesetGetByName("ui")
-- textureUi = textureLoad(tilesetUi.texture)
tilesetBorder = tilesetGetByName("border")
textureBorder = textureLoad(tilesetBorder.texture)
-- tilesetBorder = tilesetGetByName("border")
-- textureBorder = textureLoad(tilesetBorder.texture)
textureGrid = textureLoad("minesweeper/grid_bg.dpi")
-- textureGrid = textureLoad("minesweeper/grid_bg.dpi")
tilesetCell = tilesetGetByName("cell")
textureCell = textureLoad(tilesetCell.texture)
cellSliceDefault = tilesetPositionGetUV(tilesetCell, 3, 5)
cellSliceHover = tilesetPositionGetUV(tilesetCell, 3, 4)
cellSliceDown = tilesetPositionGetUV(tilesetCell, 3, 6)
cellSliceDisabled = tilesetPositionGetUV(tilesetCell, 3, 7)
-- tilesetCell = tilesetGetByName("cell")
-- textureCell = textureLoad(tilesetCell.texture)
-- cellSliceDefault = tilesetPositionGetUV(tilesetCell, 3, 5)
-- cellSliceHover = tilesetPositionGetUV(tilesetCell, 3, 4)
-- cellSliceDown = tilesetPositionGetUV(tilesetCell, 3, 6)
-- cellSliceDisabled = tilesetPositionGetUV(tilesetCell, 3, 7)
sweepwerCols = 10
sweeperRows = 14
-- sweepwerCols = 10
-- sweeperRows = 14
mouseX = -1
mouseY = -1
centerX = 0
centerY = 0
boardWidth = sweepwerCols * tilesetCell.tileWidth
boardHeight = sweeperRows * tilesetCell.tileHeight
-- mouseX = -1
-- mouseY = -1
-- centerX = 0
-- centerY = 0
-- boardWidth = sweepwerCols * tilesetCell.tileWidth
-- boardHeight = sweeperRows * tilesetCell.tileHeight
i = 0
cells = {}
for y = 1, sweeperRows do
for x = 1, sweepwerCols do
cells[i] = CELL_STATE_DEFAULT
i = i + 1
end
end
-- i = 0
-- cells = {}
-- for y = 1, sweeperRows do
-- for x = 1, sweepwerCols do
-- cells[i] = CELL_STATE_DEFAULT
-- i = i + 1
-- end
-- end
function cellDraw(x, y, type)
local slice = cellSliceDefault
@@ -189,42 +189,53 @@ function sceneRender()
mouseY = inputGetValue(INPUT_ACTION_POINTERY) * screenGetHeight()
end
centerX = math.floor(screenGetWidth() / 2)
centerY = math.floor(screenGetHeight() / 2)
-- Draw elements
backgroundDraw()
borderDraw(
centerX - (boardWidth / 2), centerY - (boardHeight / 2),
boardWidth, boardHeight
-- Draw cursor
spriteBatchPush(
nil,
mouseX - 2, mouseY - 2,
mouseX + 2, mouseY + 2,
colorRed(),
0, 0,
1, 1
)
i = 0
-- Foreach cell
local offX = centerX - (boardWidth / 2)
local offY = centerY - (boardHeight / 2)
for y = 0, sweeperRows - 1 do
for x = 0, sweepwerCols - 1 do
i = y * sweepwerCols + x
-- centerX = math.floor(screenGetWidth() / 2)
-- centerY = math.floor(screenGetHeight() / 2)
-- Draw elements
-- backgroundDraw()
-- borderDraw(
-- centerX - (boardWidth / 2), centerY - (boardHeight / 2),
-- boardWidth, boardHeight
-- )
-- i = 0
-- -- Foreach cell
-- local offX = centerX - (boardWidth / 2)
-- local offY = centerY - (boardHeight / 2)
-- for y = 0, sweeperRows - 1 do
-- for x = 0, sweepwerCols - 1 do
-- i = y * sweepwerCols + x
-- Hovered
if
cells[i] == CELL_STATE_DEFAULT and
mouseX >= x * tilesetCell.tileWidth + offX and mouseX < (x + 1) * tilesetCell.tileWidth + offX and
mouseY >= y * tilesetCell.tileHeight + offY and mouseY < (y + 1) * tilesetCell.tileHeight + offY
then
cells[i] = CELL_STATE_HOVER
else
cells[i] = CELL_STATE_DEFAULT
end
-- -- Hovered
-- if
-- cells[i] == CELL_STATE_DEFAULT and
-- mouseX >= x * tilesetCell.tileWidth + offX and mouseX < (x + 1) * tilesetCell.tileWidth + offX and
-- mouseY >= y * tilesetCell.tileHeight + offY and mouseY < (y + 1) * tilesetCell.tileHeight + offY
-- then
-- cells[i] = CELL_STATE_HOVER
-- else
-- cells[i] = CELL_STATE_DEFAULT
-- end
cellDraw(
x * tilesetCell.tileWidth + offX,
y * tilesetCell.tileHeight + offY,
cells[i]
)
end
end
-- cellDraw(
-- x * tilesetCell.tileWidth + offX,
-- y * tilesetCell.tileHeight + offY,
-- cells[i]
-- )
-- end
-- end
spriteBatchFlush()
cameraPopMatrix()

View File

@@ -1,6 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
add_asset(TILESET minogram.png type=ALPHA tileWidth=6 tileHeight=10 columns=16 rows=6)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -237,7 +237,7 @@ errorret_t assetLoad(const char_t *filename, void *output) {
for(uint_fast8_t i = 0; i < ASSET_TYPE_COUNT; i++) {
const assettypedef_t *cmp = &ASSET_TYPE_DEFINITIONS[i];
assertNotNull(cmp, "Asset type definition cannot be NULL.");
assertNotNull(cmp->extension, "Asset type definition has NULL extension.");
if(cmp->extension == NULL) continue;
if(!stringEndsWithCaseInsensitive(filename, cmp->extension)) continue;
def = cmp;
break;

View File

@@ -23,40 +23,7 @@ errorret_t assetLanguageInit(
assetlanguage_t *lang,
zip_file_t *zipFile
) {
assertNotNull(lang, "Language asset cannot be NULL");
assertNotNull(zipFile, "Zip file cannot be NULL");
assertNull(lang->zip, "Language asset zip file must be NULL.");
// I want this but ubuntu isn't compiling with it right now.
// assertTrue(zip_file_is_seekable(zipFile), "Language file must be seekable.");
// We now own the zip file handle.
lang->zip = zipFile;
// Read in the header.
zip_int64_t bytesRead = zip_fread(
lang->zip,
&lang->header,
sizeof(assetlanguageheader_t)
);
if(bytesRead != sizeof(assetlanguageheader_t)) {
zip_fclose(lang->zip);
errorThrow("Failed to read language asset header.");
}
// Fix the endianness of the header data.
for(uint32_t i = 0; i < LANG_KEY_COUNT; i++) {
lang->header.strings[i].chunk = le32toh(lang->header.strings[i].chunk);
lang->header.strings[i].offset = le32toh(lang->header.strings[i].offset);
lang->header.strings[i].length = le32toh(lang->header.strings[i].length);
}
lang->chunksOffset = zip_ftell(lang->zip);
if(lang->chunksOffset <= 0) {
zip_fclose(lang->zip);
errorThrow("Failed to get language asset chunks offset.");
}
errorOk();
errorThrow("Language asset initialization is not yet implemented.");
}
errorret_t assetLanguageRead(
@@ -66,47 +33,7 @@ errorret_t assetLanguageRead(
const uint32_t bufferSize,
uint32_t *outLength
) {
assertNotNull(lang, "Language asset cannot be NULL");
assertNotNull(lang->zip, "Language asset zip file cannot be NULL");
assertTrue(key < LANG_KEY_COUNT, "Language key out of bounds.");
// Find the string entry
assetlanguagestring_t *str = &lang->header.strings[LANG_MAP_TEST];
// If buffer is NULL, return the string length
if(buffer == NULL) {
assertNotNull(outLength, "Output length pointer cannot be NULL.");
*outLength = str->length;
errorOk();
}
// Ensure buffer is large enough
assertTrue(
bufferSize >= str->length + 1,
"Provided buffer is too small for language string."
);
// Determine the file position
zip_int64_t seekTo = lang->chunksOffset + (
(str->chunk * ASSET_LANG_CHUNK_CHAR_COUNT) + str->offset
);
// Seek
zip_int64_t result = zip_fseek(lang->zip, seekTo, SEEK_SET);
if(result != 0) {
errorThrow("Failed to seek to language string in asset.");
}
// Read
zip_int64_t readTest = zip_fread(lang->zip, buffer, str->length);
if(readTest != str->length) {
errorThrow("Failed to read test string from language asset.");
}
buffer[str->length] = '\0';
// Set str length if requested
if(outLength != NULL) *outLength = str->length;
errorOk();
errorThrow("Language string reading is not yet implemented.");
}
void assetLanguageDispose(assetlanguage_t *lang) {

View File

@@ -10,34 +10,9 @@
#include "duskdefs.h"
#include <zip.h>
#define ASSET_LANG_CHUNK_CACHE 4 // Number of chunks to cache in memory
#pragma pack(push, 1)
typedef char assetlanguagechunk_t[ASSET_LANG_CHUNK_CHAR_COUNT];
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct {
uint32_t chunk;
uint32_t offset;
uint32_t length;
} assetlanguagestring_t;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct {
assetlanguagestring_t strings[LANG_KEY_COUNT];
} assetlanguageheader_t;
#pragma pack(pop)
typedef struct {
zip_file_t *zip;
assetlanguageheader_t header;
zip_int64_t chunksOffset;
// Chunk cache
assetlanguagechunk_t chunks[ASSET_LANG_CHUNK_CACHE];
uint32_t chunkIndices[ASSET_LANG_CHUNK_CACHE];
} assetlanguage_t;
typedef struct assetcustom_s assetcustom_t;

View File

@@ -9,7 +9,7 @@
#include "assert/assert.h"
#include "display/texture.h"
errorret_t assetPaletteImageLoad(void *data, void *output) {
errorret_t assetTextureLoad(void *data, void *output) {
assertNotNull(data, "Data pointer cannot be NULL.");
assertNotNull(output, "Output pointer cannot be NULL.");

View File

@@ -12,8 +12,8 @@
#define TEXT_CHAR_START '!'
// extern texture_t DEFAULT_FONT_TEXTURE;
// #define DEFAULT_FONT_TILESET TILESET_MINOGRAM
extern texture_t DEFAULT_FONT_TEXTURE;
extern tileset_t DEFAULT_FONT_TILESET;
/**
* Initializes the text system.

View File

@@ -43,7 +43,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
// Run the initial script.
scriptcontext_t ctx;
errorChain(scriptContextInit(&ctx));
errorChain(scriptContextExecFile(&ctx, "init.dsf"));
errorChain(scriptContextExecFile(&ctx, "init.lua"));
scriptContextDispose(&ctx);
errorOk();

View File

@@ -18,18 +18,19 @@ errorret_t localeManagerInit() {
}
errorret_t localeManagerSetLocale(const dusklocale_t locale) {
assertTrue(locale < DUSK_LOCALE_COUNT, "Invalid locale.");
assertTrue(locale != DUSK_LOCALE_NULL, "Cannot set locale to NULL.");
errorThrow("Locale setting is not yet implemented.");
// assertTrue(locale < DUSK_LOCALE_COUNT, "Invalid locale.");
// assertTrue(locale != DUSK_LOCALE_NULL, "Cannot set locale to NULL.");
LOCALE.locale = locale;
char_t languageFile[FILENAME_MAX];
snprintf(
languageFile, FILENAME_MAX, "language/%s.dlf", LOCALE_INFOS[locale].file
);
assetLanguageDispose(&LOCALE.language);
memoryZero(&LOCALE.language, sizeof(assetlanguage_t));
errorChain(assetLoad(languageFile, &LOCALE.language));
errorOk();
// LOCALE.locale = locale;
// char_t languageFile[FILENAME_MAX];
// snprintf(
// languageFile, FILENAME_MAX, "language/%s.dlf", LOCALE_INFOS[locale].file
// );
// assetLanguageDispose(&LOCALE.language);
// memoryZero(&LOCALE.language, sizeof(assetlanguage_t));
// errorChain(assetLoad(languageFile, &LOCALE.language));
// errorOk();
}
void localeManagerDispose() {

View File

@@ -25,7 +25,7 @@ void moduleTileset(scriptcontext_t *ctx) {
}
lua_pop(ctx->luaState, 1); // Pop the metatable
lua_register(ctx->luaState, "tilesetGetByName", moduleTilesetGetByName);
// lua_register(ctx->luaState, "tilesetGetByName", moduleTilesetGetByName);
lua_register(ctx->luaState, "tilesetTileGetUV", moduleTilesetTileGetUV);
lua_register(
ctx->luaState, "tilesetPositionGetUV", moduleTilesetPositionGetUV
@@ -76,33 +76,33 @@ int moduleTilesetToString(lua_State *l) {
return 1;
}
int moduleTilesetGetByName(lua_State *l) {
assertNotNull(l, "Lua state cannot be NULL.");
// int moduleTilesetGetByName(lua_State *l) {
// assertNotNull(l, "Lua state cannot be NULL.");
if(!lua_isstring(l, 1)) {
lua_pushnil(l);
return 1;
}
// if(!lua_isstring(l, 1)) {
// lua_pushnil(l);
// return 1;
// }
const char_t *name = lua_tostring(l, 1);
if(name == NULL || name[0] == '\0') {
luaL_error(l, "Invalid tileset name.");
return 1;
}
// const char_t *name = lua_tostring(l, 1);
// if(name == NULL || name[0] == '\0') {
// luaL_error(l, "Invalid tileset name.");
// return 1;
// }
const tileset_t *ts = tilesetGetByName(name);
if(ts == NULL) {
lua_pushnil(l);
return 1;
}
// const tileset_t *ts = tilesetGetByName(name);
// if(ts == NULL) {
// lua_pushnil(l);
// return 1;
// }
// Lua does not own this reference
lua_pushlightuserdata(l, (void *)ts);
luaL_getmetatable(l, "tileset_mt");
lua_setmetatable(l, -2);
// // Lua does not own this reference
// lua_pushlightuserdata(l, (void *)ts);
// luaL_getmetatable(l, "tileset_mt");
// lua_setmetatable(l, -2);
return 1;
}
// return 1;
// }
int moduleTilesetTileGetUV(lua_State *l) {
assertNotNull(l, "Lua state cannot be NULL.");

View File

@@ -13,66 +13,66 @@ void moduleLocale(scriptcontext_t *context) {
assertNotNull(context, "Script context cannot be NULL");
// Execute the locale script definitions.
scriptContextExec(context, LOCALE_SCRIPT);
// scriptContextExec(context, LOCALE_SCRIPT);
lua_register(context->luaState, "localeGet", moduleLocaleGet);
lua_register(context->luaState, "localeSet", moduleLocaleSet);
lua_register(context->luaState, "localeGetName", moduleLocaleGetName);
// lua_register(context->luaState, "localeGet", moduleLocaleGet);
// lua_register(context->luaState, "localeSet", moduleLocaleSet);
// lua_register(context->luaState, "localeGetName", moduleLocaleGetName);
}
int moduleLocaleGet(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// int moduleLocaleGet(lua_State *L) {
// assertNotNull(L, "Lua state cannot be NULL");
// No arguments expected
dusklocale_t locale = LOCALE.locale;
lua_pushnumber(L, (lua_Number)locale);
return 1;
}
// // No arguments expected
// dusklocale_t locale = LOCALE.locale;
// lua_pushnumber(L, (lua_Number)locale);
// return 1;
// }
int moduleLocaleSet(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// int moduleLocaleSet(lua_State *L) {
// assertNotNull(L, "Lua state cannot be NULL");
// Requires locale ID
if(!lua_isnumber(L, 1)) {
luaL_error(L, "localeSet: Expected locale ID as first argument");
return 0;
}
// // Requires locale ID
// if(!lua_isnumber(L, 1)) {
// luaL_error(L, "localeSet: Expected locale ID as first argument");
// return 0;
// }
errorret_t err;
dusklocale_t locale = (dusklocale_t)lua_tonumber(L, 1);
if(locale >= DUSK_LOCALE_COUNT || locale == DUSK_LOCALE_NULL) {
luaL_error(L, "localeSet: Invalid locale ID");
return 0;
}
// errorret_t err;
// dusklocale_t locale = (dusklocale_t)lua_tonumber(L, 1);
// if(locale >= DUSK_LOCALE_COUNT || locale == DUSK_LOCALE_NULL) {
// luaL_error(L, "localeSet: Invalid locale ID");
// return 0;
// }
err = localeManagerSetLocale(locale);
if(err.code != ERROR_OK) {
luaL_error(L, "localeSet: Failed to set locale");
errorCatch(errorPrint(err));
return 0;
}
// err = localeManagerSetLocale(locale);
// if(err.code != ERROR_OK) {
// luaL_error(L, "localeSet: Failed to set locale");
// errorCatch(errorPrint(err));
// return 0;
// }
return 0;
}
// return 0;
// }
int moduleLocaleGetName(lua_State *L) {
assertNotNull(L, "Lua state cannot be NULL");
// int moduleLocaleGetName(lua_State *L) {
// assertNotNull(L, "Lua state cannot be NULL");
// Optional ID, otherwise return current locale name
dusklocale_t locale = LOCALE.locale;
if(lua_gettop(L) >= 1) {
if(!lua_isnumber(L, 1)) {
luaL_error(L, "localeGetName: Expected locale ID as first argument");
return 0;
}
locale = (dusklocale_t)lua_tonumber(L, 1);
if(locale >= DUSK_LOCALE_COUNT || locale == DUSK_LOCALE_NULL) {
luaL_error(L, "localeGetName: Invalid locale ID");
return 0;
}
}
// // Optional ID, otherwise return current locale name
// dusklocale_t locale = LOCALE.locale;
// if(lua_gettop(L) >= 1) {
// if(!lua_isnumber(L, 1)) {
// luaL_error(L, "localeGetName: Expected locale ID as first argument");
// return 0;
// }
// locale = (dusklocale_t)lua_tonumber(L, 1);
// if(locale >= DUSK_LOCALE_COUNT || locale == DUSK_LOCALE_NULL) {
// luaL_error(L, "localeGetName: Invalid locale ID");
// return 0;
// }
// }
const char_t *localeName = LOCALE_INFOS[locale].file;
lua_pushstring(L, localeName);
return 1;
}
// const char_t *localeName = LOCALE_INFOS[locale].file;
// lua_pushstring(L, localeName);
// return 1;
// }

View File

@@ -65,15 +65,15 @@ int moduleSysInclude(lua_State *L) {
char_t buffer[1024];
stringCopy(buffer, filename, 1024);
// Ensure it has .dsf extension
// Ensure it has .lua extension
size_t len = strlen(buffer);
if(len < 4 || strcmp(&buffer[len - 4], ".dsf") != 0) {
// Append .dsf
if(len < 4 || strcmp(&buffer[len - 4], ".lua") != 0) {
// Append .lua
if(len + 4 >= 1024) {
luaL_error(L, "Filename too long to append .dsf");
luaL_error(L, "Filename too long to append .lua");
return 0;
}
stringCopy(&buffer[len], ".dsf", 5);
stringCopy(&buffer[len], ".lua", 5);
}
// Execute the script file