Scene script

This commit is contained in:
2026-04-20 15:34:24 -05:00
parent b89ae2391b
commit b640295be2
14 changed files with 143 additions and 27 deletions
+2 -2
View File
@@ -25,7 +25,7 @@ errorret_t assetInit(void) {
}
bool_t assetFileExists(const char_t *filename) {
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
assertStrLenMax(filename, ASSET_FILE_PATH_MAX, "Filename too long.");
zip_int64_t idx = zip_name_locate(ASSET.zip, filename, 0);
if(idx < 0) return false;
@@ -38,7 +38,7 @@ errorret_t assetLoad(
void *params,
void *output
) {
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
assertStrLenMax(filename, ASSET_FILE_PATH_MAX, "Filename too long.");
assertNotNull(output, "Output pointer cannot be NULL.");
assertNotNull(loader, "Asset file loader cannot be NULL.");
+2
View File
@@ -9,6 +9,8 @@
#include "error/error.h"
#include <zip.h>
#define ASSET_FILE_PATH_MAX FILENAME_MAX
typedef struct assetfile_s assetfile_t;
typedef errorret_t (*assetfileloader_t)(assetfile_t *file);
+1 -1
View File
@@ -31,7 +31,7 @@ void consoleInit() {
// Register vars
#define REG(name, value) consoleRegVar(name, value, NULL)
REG("console", "0");
REG("console", "1");
#undef REG
// Register cmdss
+7 -1
View File
@@ -55,22 +55,28 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
errorChain(scriptContextExecFile(&ctx, "init.lua"));
scriptContextDispose(&ctx);
sceneSet("test/scene.lua");
errorOk();
}
errorret_t engineUpdate(void) {
// Order here is important.
errorChain(networkUpdate());
timeUpdate();
inputUpdate();
consoleUpdate();
uiUpdate();
errorChain(sceneUpdate());
physicsManagerUpdate();
errorChain(gameUpdate());
errorChain(displayUpdate());
if(inputPressed(INPUT_ACTION_RAGEQUIT)) ENGINE.running = false;
// Scene update occurs last because only after rendering would we want to do
// scene switching, refer to sceneSet() for information.
errorChain(sceneUpdate());
errorOk();
}
+99 -3
View File
@@ -16,6 +16,7 @@
#include "display/text/text.h"
#include "display/screen/screen.h"
#include "console/console.h"
#include "util/string.h"
scene_t SCENE;
@@ -30,6 +31,27 @@ errorret_t sceneUpdate(void) {
errorOk();
}
#endif
// Is the scene changing?
if(stringCompare(SCENE.sceneNext, SCENE.sceneCurrent) != 0) {
errorChain(sceneSetImmediate(SCENE.sceneNext));
}
// Call scene update function if script loaded
if(!SCENE.scriptActive) {
errorOk();
}
assertNotNull(SCENE.script.luaState, "Script context null?");
lua_getglobal(SCENE.script.luaState, "sceneUpdate");
if(lua_isfunction(SCENE.script.luaState, -1)) {
if(lua_pcall(SCENE.script.luaState, 0, 0, 0) != LUA_OK) {
errorThrow(
"Failed to call sceneUpdate function in script: %s\n",
lua_tostring(SCENE.script.luaState, -1)
);
}
}
errorOk();
}
@@ -42,7 +64,6 @@ errorret_t sceneRender(void) {
COMPONENT_TYPE_CAMERA, camEnts, camComps
);
// Prep Matricies
mat4 view, proj, model;
@@ -142,10 +163,85 @@ errorret_t sceneRender(void) {
errorOk();
}
errorret_t sceneSet(const char_t *script) {
errorret_t sceneSetImmediate(const char_t *script) {
// Update the next scene name (shouldn't really happen but its for safety).
if(script != SCENE.sceneNext) {
stringCopy(
SCENE.sceneNext,
script == NULL ? "" : script,
ASSET_FILE_PATH_MAX
);
}
// If there's currently a scene active, dispose of it first.
if(SCENE.scriptActive) {
assertNotNull(SCENE.script.luaState, "Script context null?");
// Call sceneDispose function
lua_getglobal(SCENE.script.luaState, "sceneDispose");
if(lua_isfunction(SCENE.script.luaState, -1)) {
if(lua_pcall(SCENE.script.luaState, 0, 0, 0) != LUA_OK) {
errorThrow(
"Failed to call sceneDispose function in script: %s\n",
lua_tostring(SCENE.script.luaState, -1)
);
}
}
// Scenes should ideally clean themselves up, this is just a warning because
// you can technically move entities between scenes, but it's messy.
for(entityid_t i = 0; i < ENTITY_COUNT_MAX; i++) {
if(ENTITY_MANAGER.entities[i].state & ENTITY_STATE_ACTIVE) {
consolePrint(
"Entity %d is active after scene dispose\n", i
);
}
}
// Unload script context.
scriptContextDispose(&SCENE.script);
SCENE.scriptActive = false;
}
// At this point the existing scene is unloaded, update the current scene.
stringCopy(
SCENE.sceneCurrent,
script == NULL ? "" : script,
ASSET_FILE_PATH_MAX
);
// If we have a new scene, execute it.
if(script != NULL) {
errorChain(scriptContextInit(&SCENE.script));
SCENE.scriptActive = true;
errorChain(scriptContextExecFile(&SCENE.script, script));
// Call the init function.
lua_getglobal(SCENE.script.luaState, "sceneInit");
if(lua_isfunction(SCENE.script.luaState, -1)) {
if(lua_pcall(SCENE.script.luaState, 0, 0, 0) != LUA_OK) {
errorThrow(
"Failed to call sceneInit function in script: %s\n",
lua_tostring(SCENE.script.luaState, -1)
);
}
}
}
errorOk();
}
void sceneDispose(void) {
void sceneSet(const char_t *script) {
// Tell the scene that next update it needs to change scenes. This will always
// occur on the NEXT frame.
stringCopy(
SCENE.sceneNext,
script == NULL ? "" : script,
ASSET_FILE_PATH_MAX
);
}
errorret_t sceneDispose(void) {
errorChain(sceneSetImmediate(NULL));
errorOk();
}
+17 -4
View File
@@ -6,10 +6,14 @@
*/
#pragma once
#include "error/error.h"
#include "script/scriptcontext.h"
#include "asset/assetfile.h"
typedef struct {
void *nothing;
scriptcontext_t script;
bool_t scriptActive;
char_t sceneCurrent[ASSET_FILE_PATH_MAX];
char_t sceneNext[ASSET_FILE_PATH_MAX];
} scene_t;
extern scene_t SCENE;
@@ -35,14 +39,23 @@ errorret_t sceneUpdate(void);
*/
errorret_t sceneRender(void);
/**
* Internal only method, immediately sets the scene. This will basically crash
* Lua if called from its tree.
*/
errorret_t sceneSetImmediate(const char_t *script);
/**
* Set the current scene by script name.
*
* @param script The script name of the scene to set.
* @return The error return value.
*/
errorret_t sceneSet(const char_t *script);
void sceneSet(const char_t *script);
/**
* Dispose of the scene subsystem.
*
* @return The error return value.
*/
void sceneDispose(void);
errorret_t sceneDispose(void);
+1 -6
View File
@@ -26,12 +26,7 @@ int moduleSceneSet(lua_State *L) {
const char_t *script = lua_tostring(L, 1);
errorret_t err = sceneSet(script);
if(err.code != ERROR_OK) {
errorCatch(errorPrint(err));
luaL_error(L, "Failed to set scene");
return 0;
}
sceneSet(script);
return 0;
}
+1
View File
@@ -18,6 +18,7 @@ void stringCopy(char_t *dest, const char_t *src, const size_t destSize) {
assertNotNull(src, "src must not be NULL");
assertTrue(destSize > 0, "destSize must be greater than 0");
assertStrLenMax(src, destSize, "src is too long");
assertTrue(dest != src, "Cannot copy string to itself.");
memoryCopy(dest, src, strlen(src) + 1);
}
+2 -2
View File
@@ -21,7 +21,7 @@ errorret_t assetInitDolphin(void) {
if(!fatInitDefault()) errorThrow("Failed to initialize FAT filesystem.");
char_t **dolphinSearchPath = (char_t **)ASSET_DOLPHIN_PATHS;
char_t foundPath[FILENAME_MAX];
char_t foundPath[ASSET_FILE_PATH_MAX];
foundPath[0] = '\0';
do {
// Try open dir
@@ -40,7 +40,7 @@ errorret_t assetInitDolphin(void) {
// Copy out filename
snprintf(
foundPath,
FILENAME_MAX,
ASSET_FILE_PATH_MAX,
"%s/%s",
*dolphinSearchPath,
ASSET_FILE_NAME
+1
View File
@@ -7,6 +7,7 @@
#pragma once
#include "error/error.h"
#include "asset/assetfile.h"
static const char_t *ASSET_DOLPHIN_PATHS[] = {
"/",
+6 -6
View File
@@ -14,12 +14,12 @@ errorret_t assetInitLinux(void) {
// Engine may have been provided the launch path
if(ENGINE.argc > 0) {
// Get the directory of the executable
char_t buffer[FILENAME_MAX];
stringCopy(buffer, ENGINE.argv[0], FILENAME_MAX);
char_t buffer[ASSET_FILE_PATH_MAX];
stringCopy(buffer, ENGINE.argv[0], ASSET_FILE_PATH_MAX);
size_t len = strlen(buffer);
// Normalize slashes
for(size_t i = 0; i < FILENAME_MAX; i++) {
for(size_t i = 0; i < ASSET_FILE_PATH_MAX; i++) {
if(buffer[i] == '\0') break;
if(buffer[i] == '\\') buffer[i] = '/';
}
@@ -38,15 +38,15 @@ errorret_t assetInitLinux(void) {
// Did we find a slash?
if(end != buffer) {
// We found the directory, set as system path
stringCopy(ASSET.platform.systemPath, buffer, FILENAME_MAX);
stringCopy(ASSET.platform.systemPath, buffer, ASSET_FILE_PATH_MAX);
}
}
// Default system path, intended to be overridden by the platform
stringCopy(ASSET.platform.systemPath, ".", FILENAME_MAX);
stringCopy(ASSET.platform.systemPath, ".", ASSET_FILE_PATH_MAX);
// Open zip file
char_t searchPath[FILENAME_MAX];
char_t searchPath[ASSET_FILE_PATH_MAX];
const char_t **path = ASSET_LINUX_SEARCH_PATHS;
int32_t error;
do {
+2 -1
View File
@@ -7,6 +7,7 @@
#pragma once
#include "error/error.h"
#include "asset/assetfile.h"
static const char_t *ASSET_LINUX_SEARCH_PATHS[] = {
"%s/%s",
@@ -19,7 +20,7 @@ static const char_t *ASSET_LINUX_SEARCH_PATHS[] = {
};
typedef struct {
char_t systemPath[FILENAME_MAX];
char_t systemPath[ASSET_FILE_PATH_MAX];
} assetlinux_t;
/**
+1 -1
View File
@@ -12,7 +12,7 @@
errorret_t assetInitPBP(const char_t *pbpPath) {
assertNotNull(pbpPath, "PBP path cannot be null.");
assertStrLenMin(pbpPath, 1, "PBP path cannot be empty.");
assertStrLenMax(pbpPath, FILENAME_MAX, "PBP path is too long.");
assertStrLenMax(pbpPath, ASSET_FILE_PATH_MAX, "PBP path is too long.");
ASSET.platform.pbpFile = fopen(pbpPath, "rb");
if(ASSET.platform.pbpFile == NULL) {
+1
View File
@@ -7,6 +7,7 @@
#pragma once
#include "error/error.h"
#include "asset/assetfile.h"
#define ASSET_PBP_SIGNATURE_SIZE 4
#define ASSET_PBP_SIGNATURE "\0PBP"