Scene script
This commit is contained in:
@@ -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.");
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
+100
-4
@@ -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;
|
||||
|
||||
@@ -31,6 +32,27 @@ errorret_t sceneUpdate(void) {
|
||||
}
|
||||
#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
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
#include "asset/assetfile.h"
|
||||
|
||||
static const char_t *ASSET_DOLPHIN_PATHS[] = {
|
||||
"/",
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user