Nuke error.hpp
Some checks failed
Build Dusk / build-linux (push) Failing after 2m7s
Build Dusk / build-psp (push) Failing after 2m19s

This commit is contained in:
2025-12-22 14:19:07 +10:00
parent 76b5c51ab6
commit 2e0f5f302b
49 changed files with 418 additions and 708 deletions

View File

@@ -48,7 +48,6 @@ add_subdirectory(asset)
add_subdirectory(debug)
add_subdirectory(display)
add_subdirectory(engine)
add_subdirectory(error)
add_subdirectory(input)
add_subdirectory(locale)
add_subdirectory(rpg)

View File

@@ -10,14 +10,16 @@
#include "util/string.hpp"
#include "assert/assert.hpp"
#include "asset/assettype.h"
#include "engine/engine.hpp"
#include "engine/Engine.hpp"
#include "debug/debug.hpp"
errorret_t assetInit(void) {
using namespace Dusk;
void assetInit(void) {
memoryZero(&ASSET, sizeof(asset_t));
// Engine may have been provided the launch path
if(ENGINE.argc > 0) {
if(Engine::ENGINE.argc > 0) {
// This first arg is the executable, so on most platforms it is say
// "/path/file" or "C:\Path\file.exe". On PSP this would be something
// like "ms0:/PSP/GAME/DUSK/EBOOT.PBP" or if we are debugging it is
@@ -25,7 +27,7 @@ errorret_t assetInit(void) {
// Get the directory of the executable
char_t buffer[FILENAME_MAX];
stringCopy(buffer, ENGINE.argv[0], FILENAME_MAX);
stringCopy(buffer, Engine::ENGINE.argv[0], FILENAME_MAX);
size_t len = strlen(buffer);
// Normalize slashes
@@ -69,20 +71,26 @@ errorret_t assetInit(void) {
);
ASSET.pbpFile = fopen(pbpPath, "rb");
if(ASSET.pbpFile == NULL) {
errorThrow("Failed to open PBP file: %s", pbpPath);
throw std::runtime_error(
"Failed to open PBP file: " + std::string(pbpPath)
);
}
// Get size of PBP file.
if(fseek(ASSET.pbpFile, 0, SEEK_END) != 0) {
fclose(ASSET.pbpFile);
errorThrow("Failed to seek to end of PBP file : %s", pbpPath);
throw std::runtime_error(
"Failed to seek to end of PBP file : " + std::string(pbpPath)
);
}
size_t pbpSize = ftell(ASSET.pbpFile);
// Rewind to start
if(fseek(ASSET.pbpFile, 0, SEEK_SET) != 0) {
fclose(ASSET.pbpFile);
errorThrow("Failed to seek to start of PBP file : %s", pbpPath);
throw std::runtime_error(
"Failed to seek to start of PBP file : " + std::string(pbpPath)
);
}
// Read the PBP header
@@ -94,7 +102,9 @@ errorret_t assetInit(void) {
);
if(read != sizeof(assetpbp_t)) {
fclose(ASSET.pbpFile);
errorThrow("Failed to read PBP header", pbpPath);
throw std::runtime_error(
"Failed to read PBP header: " + std::string(pbpPath)
);
}
if(memoryCompare(
@@ -103,13 +113,17 @@ errorret_t assetInit(void) {
sizeof(ASSET_PBP_SIGNATURE)
) != 0) {
fclose(ASSET.pbpFile);
errorThrow("Invalid PBP signature in file: %s", pbpPath);
throw std::runtime_error(
"Invalid PBP signature in file: " + std::string(pbpPath)
);
}
// If we seek to the PSAR offset, we can read the WAD file from there
if(fseek(ASSET.pbpFile, ASSET.pbpHeader.psarOffset, SEEK_SET) != 0) {
fclose(ASSET.pbpFile);
errorThrow("Failed to seek to PSAR offset in PBP file: %s", pbpPath);
throw std::runtime_error(
"Failed to seek to PSAR offset in PBP file: " + std::string(pbpPath)
);
}
zip_uint64_t zipPsarOffset = (zip_uint64_t)ASSET.pbpHeader.psarOffset;
@@ -125,7 +139,9 @@ errorret_t assetInit(void) {
);
if(psarSource == NULL) {
fclose(ASSET.pbpFile);
errorThrow("Failed to create zip source in PBP file: %s", pbpPath);
throw std::runtime_error(
"Failed to create zip source in PBP file: " + std::string(pbpPath)
);
}
ASSET.zip = zip_open_from_source(
@@ -136,7 +152,9 @@ errorret_t assetInit(void) {
if(ASSET.zip == NULL) {
zip_source_free(psarSource);
fclose(ASSET.pbpFile);
errorThrow("Failed to open zip from PBP file: %s", pbpPath);
throw std::runtime_error(
"Failed to open zip from PBP file: " + std::string(pbpPath)
);
}
errorOk();
@@ -162,9 +180,7 @@ errorret_t assetInit(void) {
} while(*(++path) != NULL);
// Did we open the asset?
if(ASSET.zip == NULL) errorThrow("Failed to open asset file.");
errorOk();
if(ASSET.zip == NULL) throw std::runtime_error("Failed to open asset file.");
}
bool_t assetFileExists(const char_t *filename) {
@@ -175,14 +191,16 @@ bool_t assetFileExists(const char_t *filename) {
return true;
}
errorret_t assetLoad(const char_t *filename, void *output) {
void assetLoad(const char_t *filename, void *output) {
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
assertNotNull(output, "Output pointer cannot be NULL.");
// Try to open the file
zip_file_t *file = zip_fopen(ASSET.zip, filename, 0);
if(file == NULL) {
errorThrow("Failed to open asset file: %s", filename);
throw std::runtime_error(
"Failed to open asset file: " + std::string(filename)
);
}
// Read the header.
@@ -191,7 +209,9 @@ errorret_t assetLoad(const char_t *filename, void *output) {
zip_int64_t bytesRead = zip_fread(file, &header, sizeof(assetheader_t));
if(bytesRead != sizeof(assetheader_t)) {
zip_fclose(file);
errorThrow("Failed to read asset header for: %s", filename);
throw std::runtime_error(
"Failed to read asset header for: " + std::string(filename)
);
}
// Find the asset type based on the header
@@ -215,7 +235,9 @@ errorret_t assetLoad(const char_t *filename, void *output) {
}
if(def == NULL) {
zip_fclose(file);
errorThrow("Unknown asset type for file: %s", filename);
throw std::runtime_error(
"Unknown asset type for file: " + std::string(filename)
);
}
// We found the asset type, now load the asset data
@@ -227,16 +249,24 @@ errorret_t assetLoad(const char_t *filename, void *output) {
if(bytesRead == 0 || bytesRead > def->dataSize) {
memoryFree(data);
zip_fclose(file);
errorThrow("Failed to read asset data for file: %s", filename);
throw std::runtime_error(
"Failed to read entire asset data for file: " +
std::string(filename)
);
}
// Close the file now we have the data
zip_fclose(file);
// Pass to the asset type loader
errorret_t ret = def->entire(data, output);
try {
def->entire(data, output);
} catch(...) {
memoryFree(data);
throw;
}
memoryFree(data);
errorChain(ret);
break;
}
@@ -246,15 +276,13 @@ errorret_t assetLoad(const char_t *filename, void *output) {
.zipFile = file,
.output = output
};
errorChain(def->custom(customData));
def->custom(customData);
break;
}
default:
assertUnreachable("Unknown asset load strategy.");
}
errorOk();
}
void assetDispose(void) {

View File

@@ -6,7 +6,6 @@
*/
#pragma once
#include "error/error.hpp"
#include "assettype.h"
#if ASSET_TYPE == wad
@@ -67,7 +66,7 @@ static asset_t ASSET;
/**
* Initializes the asset system.
*/
errorret_t assetInit(void);
void assetInit(void);
/**
* Checks if an asset file exists.
@@ -84,7 +83,7 @@ bool_t assetFileExists(const char_t *filename);
* @param output The output pointer to store the loaded asset data.
* @return An error code if the asset could not be loaded.
*/
errorret_t assetLoad(const char_t *filename, void *output);
void assetLoad(const char_t *filename, void *output);
/**
* Disposes/cleans up the asset system.

View File

@@ -41,8 +41,8 @@ typedef struct {
const assetloadstrat_t loadStrategy;
const size_t dataSize;
union {
errorret_t (*entire)(void *data, void *output);
errorret_t (*custom)(assetcustom_t custom);
void (*entire)(void *data, void *output);
void (*custom)(assetcustom_t custom);
};
} assettypedef_t;

View File

@@ -9,7 +9,7 @@
#include "assert/assert.hpp"
#include "display/texture.hpp"
errorret_t assetAlphaImageLoad(void *data, void *output) {
void assetAlphaImageLoad(void *data, void *output) {
assertNotNull(data, "Data pointer cannot be NULL.");
assertNotNull(output, "Output pointer cannot be NULL.");
@@ -23,6 +23,4 @@ errorret_t assetAlphaImageLoad(void *data, void *output) {
TEXTURE_FORMAT_ALPHA,
(texturedata_t){ .alpha = { .data = dataPtr->pixels } }
);
errorOk();
}

View File

@@ -6,7 +6,7 @@
*/
#pragma once
#include "error/error.hpp"
#include "dusk.hpp"
#define ASSET_ALPHA_IMAGE_WIDTH_MAX 256
#define ASSET_ALPHA_IMAGE_HEIGHT_MAX 256
@@ -27,6 +27,6 @@ typedef struct {
* be of type ASSET_TYPE_ALPHA_IMAGE and must be loaded.
*
* @param asset The asset to load the alpha image from.
* @return An error code.
* @throws std::runtime_error if loading fails.
*/
errorret_t assetAlphaImageLoad(void *data, void *output);
void assetAlphaImageLoad(void *data, void *output);

View File

@@ -38,7 +38,7 @@ typedef struct {
} assetchunkentityheader_t;
#pragma pack(pop)
errorret_t assetChunkLoad(assetcustom_t custom) {
void assetChunkLoad(assetcustom_t custom) {
assertNotNull(custom.output, "Output pointer cannot be NULL");
assertNotNull(custom.zipFile, "Zip file pointer cannot be NULL");
@@ -52,33 +52,33 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
);
if(bytesRead != sizeof(assetchunkheader_t)) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk asset header.");
throw std::runtime_error("Failed to read chunk asset header.");
}
if(header.tileCount != CHUNK_TILE_COUNT) {
zip_fclose(custom.zipFile);
errorThrow(
"Chunk asset has invalid tile count: %d (expected %d).",
header.tileCount,
CHUNK_TILE_COUNT
throw std::runtime_error(
"Chunk asset has invalid tile count: " +
std::to_string(header.tileCount) +
" (expected " + std::to_string(CHUNK_TILE_COUNT) + ")."
);
}
if(header.modelCount > CHUNK_MESH_COUNT_MAX) {
zip_fclose(custom.zipFile);
errorThrow(
"Chunk asset has too many models: %d (max %d).",
header.modelCount,
CHUNK_MESH_COUNT_MAX
throw std::runtime_error(
"Chunk asset has too many models: " +
std::to_string(header.modelCount) +
" (max " + std::to_string(CHUNK_MESH_COUNT_MAX) + ")."
);
}
if(header.entityCount > CHUNK_ENTITY_COUNT_MAX) {
zip_fclose(custom.zipFile);
errorThrow(
"Chunk asset has too many entities: %d (max %d).",
header.entityCount,
CHUNK_ENTITY_COUNT_MAX
throw std::runtime_error(
"Chunk asset has too many entities: " +
std::to_string(header.entityCount) +
" (max " + std::to_string(CHUNK_ENTITY_COUNT_MAX) + ")."
);
}
@@ -92,7 +92,7 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
);
if(bytesRead != sizeof(assetchunktiledata_t) * header.tileCount) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk tile data.");
throw std::runtime_error("Failed to read chunk tile data.");
}
// For each model...
@@ -104,7 +104,7 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
);
if(bytesRead != sizeof(assetchunkmodelheader_t)) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk model header.");
throw std::runtime_error("Failed to read chunk model header.");
}
if(
@@ -112,7 +112,7 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
CHUNK_VERTEX_COUNT_MAX
) {
zip_fclose(custom.zipFile);
errorThrow("Chunk model vertex count exceeds maximum.");
throw std::runtime_error("Chunk model vertex count exceeds maximum.");
}
// Read vertex data.
@@ -123,7 +123,7 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
);
if(bytesRead != sizeof(meshvertex_t) * modelHeader.vertexCount) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk model vertex data.");
throw std::runtime_error("Failed to read chunk model vertex data.");
}
// Init the mesh
@@ -150,13 +150,13 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
);
if(bytesRead != sizeof(assetchunkentityheader_t)) {
zip_fclose(custom.zipFile);
errorThrow("Failed to read chunk entity header.");
throw std::runtime_error("Failed to read chunk entity header.");
}
uint8_t entityIndex = entityGetAvailable();
if(entityIndex == 0xFF) {
zip_fclose(custom.zipFile);
errorThrow("No available entity slots.");
throw std::runtime_error("No available entity slots.");
}
entity_t *entity = &ENTITIES[entityIndex];
@@ -173,6 +173,4 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
chunk->entities[i] = entityIndex;
}
errorOk();
}

View File

@@ -6,7 +6,6 @@
*/
#pragma once
#include "error/error.hpp"
#include "rpg/world/chunk.hpp"
typedef struct assetcustom_s assetcustom_t;
@@ -15,6 +14,6 @@ typedef struct assetcustom_s assetcustom_t;
* Handles loading of chunk data from a chunk asset file.
*
* @param custom The custom asset loading parameters.
* @return An error code.
* @throws std::runtime_error if loading fails.
*/
errorret_t assetChunkLoad(assetcustom_t custom);
void assetChunkLoad(assetcustom_t custom);

View File

@@ -9,17 +9,15 @@
#include "assert/assert.hpp"
#include "locale/localemanager.hpp"
errorret_t assetLanguageHandler(assetcustom_t custom) {
void assetLanguageHandler(assetcustom_t custom) {
assertNotNull(custom.zipFile, "Custom asset zip file cannot be NULL");
assertNotNull(custom.output, "Custom asset output cannot be NULL");
assetlanguage_t *lang = (assetlanguage_t *)custom.output;
errorChain(assetLanguageInit(lang, custom.zipFile));
errorOk();
assetLanguageInit(lang, custom.zipFile);
}
errorret_t assetLanguageInit(
void assetLanguageInit(
assetlanguage_t *lang,
zip_file_t *zipFile
) {
@@ -40,19 +38,17 @@ errorret_t assetLanguageInit(
);
if(bytesRead != sizeof(assetlanguageheader_t)) {
zip_fclose(lang->zip);
errorThrow("Failed to read language asset header.");
throw std::runtime_error("Failed to read language asset header.");
}
lang->chunksOffset = zip_ftell(lang->zip);
if(lang->chunksOffset <= 0) {
zip_fclose(lang->zip);
errorThrow("Failed to get language asset chunks offset.");
throw std::runtime_error("Failed to get language asset chunks offset.");
}
}
errorOk();
}
errorret_t assetLanguageRead(
void assetLanguageRead(
assetlanguage_t *lang,
const uint32_t key,
char_t *buffer,
@@ -70,7 +66,7 @@ errorret_t assetLanguageRead(
if(buffer == NULL) {
assertNotNull(outLength, "Output length pointer cannot be NULL.");
*outLength = str->length;
errorOk();
return;
}
// Ensure buffer is large enough
@@ -87,19 +83,19 @@ errorret_t assetLanguageRead(
// Seek
zip_int64_t result = zip_fseek(lang->zip, seekTo, SEEK_SET);
if(result != 0) {
errorThrow("Failed to seek to language string in asset.");
throw std::runtime_error("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.");
throw std::runtime_error("Failed to read test string from language asset.");
}
buffer[str->length] = '\0';
// Set str length if requested
if(outLength != NULL) *outLength = str->length;
errorOk();
return;
}
void assetLanguageDispose(assetlanguage_t *lang) {

View File

@@ -7,7 +7,6 @@
#pragma once
#include "locale/language/keys.hpp"
#include "error/error.hpp"
#include "duskdefs.hpp"
#include <zip.h>
@@ -47,18 +46,18 @@ typedef struct assetcustom_s assetcustom_t;
* Receiving function from the asset manager to handle language assets.
*
* @param custom Custom asset loading data.
* @return Error code.
* @throws std::runtime_error if loading fails.
*/
errorret_t assetLanguageHandler(assetcustom_t custom);
void assetLanguageHandler(assetcustom_t custom);
/**
* Initializes a language asset and loads the header data into memory.
*
* @param lang Language asset to initialize.
* @param zipFile Zip file handle for the language asset.
* @return Error code.
* @throws std::runtime_error if loading fails.
*/
errorret_t assetLanguageInit(assetlanguage_t *lang, zip_file_t *zipFile);
void assetLanguageInit(assetlanguage_t *lang, zip_file_t *zipFile);
/**
* Reads a string from the language asset into the provided buffer.
@@ -68,9 +67,9 @@ errorret_t assetLanguageInit(assetlanguage_t *lang, zip_file_t *zipFile);
* @param buffer Buffer to read the string into.
* @param bufferSize Size of the provided buffer.
* @param outLength Pointer to store the length of the string read.
* @return Error code.
* @throws std::runtime_error if loading fails.
*/
errorret_t assetLanguageRead(
void assetLanguageRead(
assetlanguage_t *lang,
const uint32_t key,
char_t *buffer,
@@ -82,6 +81,6 @@ errorret_t assetLanguageRead(
* Disposes of language asset resources.
*
* @param custom Custom asset loading data.
* @return Error code.
* @throws std::runtime_error if loading fails.
*/
void assetLanguageDispose(assetlanguage_t *lang);

View File

@@ -9,11 +9,9 @@
#include "assert/assert.hpp"
#include "util/memory.hpp"
errorret_t assetMapLoad(void *data, void *output) {
void assetMapLoad(void *data, void *output) {
assertNotNull(data, "Data cannot be NULL");
assertNotNull(output, "Output cannot be NULL");
assertUnreachable("map not finished");
errorOk();
}

View File

@@ -6,7 +6,6 @@
*/
#pragma once
#include "error/error.hpp"
#include "rpg/world/map.hpp"
#include "display/mesh/mesh.hpp"
@@ -15,6 +14,6 @@
*
* @param data Pointer to the raw assetmap_t data.
* @param output Pointer to the map_t to load the map into.
* @return An error code.
* @throws std::runtime_error if loading fails.
*/
errorret_t assetMapLoad(void *data, void *output);
void assetMapLoad(void *data, void *output);

View File

@@ -9,7 +9,7 @@
#include "assert/assert.hpp"
#include "display/texture.hpp"
errorret_t assetPaletteImageLoad(void *data, void *output) {
void assetPaletteImageLoad(void *data, void *output) {
assertNotNull(data, "Data pointer cannot be NULL.");
assertNotNull(output, "Output pointer cannot be NULL.");
@@ -28,6 +28,4 @@ errorret_t assetPaletteImageLoad(void *data, void *output) {
}
}
);
errorOk();
}

View File

@@ -6,7 +6,7 @@
*/
#pragma once
#include "error/error.hpp"
#include "dusk.hpp"
#define ASSET_PALETTE_IMAGE_WIDTH_MAX 128
#define ASSET_PALETTE_IMAGE_HEIGHT_MAX 128
@@ -29,6 +29,6 @@ typedef struct {
*
* @param data Pointer to the raw assetpaletteimage_t data.
* @param output Pointer to the texture_t to load the image into.
* @return An error code.
* @throws std::runtime_error if loading fails.
*/
errorret_t assetPaletteImageLoad(void *data, void *output);
void assetPaletteImageLoad(void *data, void *output);

View File

@@ -8,17 +8,15 @@
#include "asset/asset.hpp"
#include "assert/assert.hpp"
errorret_t assetScriptHandler(assetcustom_t custom) {
void assetScriptHandler(assetcustom_t custom) {
assertNotNull(custom.zipFile, "Custom asset zip file cannot be NULL");
assertNotNull(custom.output, "Custom asset output cannot be NULL");
assetscript_t *script = (assetscript_t *)custom.output;
errorChain(assetScriptInit(script, custom.zipFile));
errorOk();
assetScriptInit(script, custom.zipFile);
}
errorret_t assetScriptInit(
void assetScriptInit(
assetscript_t *script,
zip_file_t *zipFile
) {
@@ -27,8 +25,6 @@ errorret_t assetScriptInit(
// We now own the zip file handle.
script->zip = zipFile;
errorOk();
}
const char_t * assetScriptReader(lua_State* lState, void* data, size_t* size) {
@@ -46,13 +42,11 @@ const char_t * assetScriptReader(lua_State* lState, void* data, size_t* size) {
return script->buffer;
}
errorret_t assetScriptDispose(assetscript_t *script) {
void assetScriptDispose(assetscript_t *script) {
assertNotNull(script, "Script asset cannot be NULL");
if(script->zip != NULL) {
zip_fclose(script->zip);
script->zip = NULL;
}
errorOk();
}

View File

@@ -6,7 +6,7 @@
*/
#pragma once
#include "error/error.hpp"
#include "dusk.hpp"
#include "duskdefs.hpp"
#include <zip.h>
#include "script/scriptcontext.hpp"
@@ -24,18 +24,18 @@ typedef struct assetcustom_s assetcustom_t;
* Receiving function from the asset manager to handle script assets.
*
* @param custom Custom asset loading data.
* @return Error code.
* @throws std::runtime_error on failure.
*/
errorret_t assetScriptHandler(assetcustom_t custom);
void assetScriptHandler(assetcustom_t custom);
/**
* Initializes a script asset.
*
* @param script Script asset to initialize.
* @param zipFile Zip file handle for the script asset.
* @return Error code.
* @throws std::runtime_error on failure.
*/
errorret_t assetScriptInit(assetscript_t *script, zip_file_t *zipFile);
void assetScriptInit(assetscript_t *script, zip_file_t *zipFile);
/**
* Reader function for Lua to read script data from the asset.
@@ -51,7 +51,7 @@ const char_t * assetScriptReader(lua_State* L, void* data, size_t* size);
* Disposes of a script asset, freeing any allocated resources.
*
* @param script Script asset to dispose of.
* @return Error code.
* @throws std::runtime_error on failure.
*/
errorret_t assetScriptDispose(assetscript_t *script);
void assetScriptDispose(assetscript_t *script);

View File

@@ -6,7 +6,7 @@
*/
#include "display/display.hpp"
#include "engine/engine.hpp"
#include "engine/Engine.hpp"
#include "display/framebuffer.hpp"
#include "scene/scenemanager.hpp"
#include "display/spritebatch.hpp"
@@ -15,16 +15,20 @@
#include "ui/ui.hpp"
#include "debug/debug.hpp"
using namespace Dusk;
display_t DISPLAY;
errorret_t displayInit(void) {
void displayInit(void) {
#if DISPLAY_SDL2
uint32_t flags = SDL_INIT_VIDEO;
#if INPUT_GAMEPAD == 1
flags |= SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK;
#endif
if(SDL_Init(flags) != 0) {
errorThrow("SDL Failed to Initialize: %s", SDL_GetError());
throw std::runtime_error(
"SDL Failed to Initialize " + std::string(SDL_GetError())
);
}
// Set OpenGL attributes (Needs to be done now or later?)
@@ -41,13 +45,17 @@ errorret_t displayInit(void) {
SDL_WINDOW_OPENGL
);
if(!DISPLAY.window) {
errorThrow("SDL_CreateWindow failed: %s", SDL_GetError());
throw std::runtime_error(
"SDL_CreateWindow failed: " + std::string(SDL_GetError())
);
}
// Create OpenGL context
DISPLAY.glContext = SDL_GL_CreateContext(DISPLAY.window);
if(!DISPLAY.glContext) {
errorThrow("SDL_GL_CreateContext failed: %s", SDL_GetError());
throw std::runtime_error(
"SDL_GL_CreateContext failed: " + std::string(SDL_GetError())
);
}
SDL_GL_SetSwapInterval(1);
@@ -74,24 +82,22 @@ errorret_t displayInit(void) {
frameBufferInitBackbuffer();
spriteBatchInit();
screenInit();
errorOk();
}
errorret_t displayUpdate(void) {
void displayUpdate(void) {
#if DISPLAY_SDL2
SDL_Event event;
while(SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_QUIT: {
ENGINE.running = false;
Engine::ENGINE.exit();
break;
}
case SDL_WINDOWEVENT: {
switch(event.window.event) {
case SDL_WINDOWEVENT_CLOSE: {
ENGINE.running = false;
Engine::ENGINE.exit();
break;
}
@@ -136,12 +142,9 @@ errorret_t displayUpdate(void) {
while((err = glGetError()) != GL_NO_ERROR) {
debugPrint("GL Error: %d\n", err);
}
// For now, we just return an OK error.
errorOk();
}
errorret_t displayDispose(void) {
void displayDispose(void) {
spriteBatchDispose();
screenDispose();
@@ -156,7 +159,4 @@ errorret_t displayDispose(void) {
}
SDL_Quit();
#endif
// For now, we just return an OK error.
errorOk();
}

View File

@@ -7,7 +7,6 @@
#pragma once
#include "displaydefs.hpp"
#include "error/error.hpp"
#include "display/camera.hpp"
#include "display/framebuffer.hpp"
@@ -23,14 +22,14 @@ extern display_t DISPLAY;
/**
* Initializes the display system.
*/
errorret_t displayInit(void);
void displayInit(void);
/**
* Tells the display system to actually draw the frame.
*/
errorret_t displayUpdate(void);
void displayUpdate(void);
/**
* Disposes of the display system.
*/
errorret_t displayDispose(void);
void displayDispose(void);

View File

@@ -36,3 +36,10 @@ extern "C" {
typedef float float_t;
typedef char char_t;
}
#include <string>
#include <vector>
#include <map>
#include <stdexcept>
#include <functional>
#include <memory>

View File

@@ -6,5 +6,5 @@
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
engine.cpp
Engine.cpp
)

83
src/engine/Engine.cpp Normal file
View File

@@ -0,0 +1,83 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "Engine.hpp"
#include "util/memory.hpp"
#include "time/time.hpp"
#include "input/input.hpp"
#include "locale/localemanager.hpp"
#include "display/display.hpp"
#include "scene/scenemanager.hpp"
#include "asset/asset.hpp"
#include "ui/ui.hpp"
#include "rpg/rpg.hpp"
#include "script/scriptmanager.hpp"
#include "debug/debug.hpp"
#include "script/scriptcontext.hpp"
using namespace Dusk;
Engine Engine::ENGINE;
Engine::Engine() :
running(false),
argc(0),
argv(nullptr)
{
}
void Engine::init(const int32_t argc, const char_t **argv) {
this->running = true;
this->argc = argc;
this->argv = argv;
// Init systems. Order is important.
timeInit();
inputInit();
assetInit();
localeManagerInit();
scriptManagerInit();
displayInit();
uiInit();
rpgInit();
sceneManagerInit();
// Run the initial script.
scriptcontext_t testCtx;
scriptContextInit(&testCtx);
scriptContextExecFile(&testCtx, "script/test.dsf");
scriptContextDispose(&testCtx);
}
void Engine::update() {
timeUpdate();
inputUpdate();
rpgUpdate();
uiUpdate();
sceneManagerUpdate();
displayUpdate();
if(inputPressed(INPUT_ACTION_RAGEQUIT)) this->running = false;
}
void Engine::dispose() {
localeManagerDispose();
sceneManagerDispose();
rpgDispose();
uiDispose();
displayDispose();
assetDispose();
}
void Engine::exit() {
this->running = false;
}
bool_t Engine::isRunning() {
return this->running;
}

56
src/engine/Engine.hpp Normal file
View File

@@ -0,0 +1,56 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/display.hpp"// Important to be included first.
namespace Dusk {
struct Engine {
private:
bool running;
public:
static Engine ENGINE;
int32_t argc;
const char_t **argv;
/**
* Initializes the engine.
*/
Engine();
/**
* Initializes the engine.
*
* @param argc The argument count from main().
* @param argv The argument vector from main().
*/
void init(const int32_t argc, const char_t **argv);
/**
* Updates the engine.
*/
void update();
/**
* Disposes of the engine.
*/
void dispose();
/**
* Requests the engine to exit.
*/
void exit();
/**
* Returns whether the engine is exiting or running.
*
* @return True if the engine is running, false otherwise.
*/
bool_t isRunning();
};
}

View File

@@ -1,80 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "engine.hpp"
#include "util/memory.hpp"
#include "time/time.hpp"
#include "input/input.hpp"
#include "locale/localemanager.hpp"
#include "display/display.hpp"
#include "scene/scenemanager.hpp"
#include "asset/asset.hpp"
#include "ui/ui.hpp"
#include "rpg/rpg.hpp"
#include "script/scriptmanager.hpp"
#include "debug/debug.hpp"
#include "script/scriptcontext.hpp"
engine_t ENGINE;
errorret_t engineInit(const int32_t argc, const char_t **argv) {
memoryZero(&ENGINE, sizeof(engine_t));
ENGINE.running = true;
ENGINE.argc = argc;
ENGINE.argv = argv;
// Init systems. Order is important.
timeInit();
inputInit();
errorChain(assetInit());
errorChain(localeManagerInit());
errorChain(scriptManagerInit());
errorChain(displayInit());
errorChain(uiInit());
errorChain(rpgInit());
errorChain(sceneManagerInit());
// Run the initial script.
scriptcontext_t testCtx;
errorChain(scriptContextInit(&testCtx));
errorChain(scriptContextExecFile(&testCtx, "script/test.dsf"));
scriptContextDispose(&testCtx);
errorOk();
}
errorret_t engineUpdate(void) {
timeUpdate();
inputUpdate();
errorChain(rpgUpdate());
uiUpdate();
sceneManagerUpdate();
errorChain(displayUpdate());
if(inputPressed(INPUT_ACTION_RAGEQUIT)) ENGINE.running = false;
errorOk();
}
void engineExit(void) {
ENGINE.running = false;
}
errorret_t engineDispose(void) {
localeManagerDispose();
sceneManagerDispose();
rpgDispose();
uiDispose();
errorChain(displayDispose());
assetDispose();
errorOk();
}

View File

@@ -1,36 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "display/display.hpp"// Important to be included first.
#include "error/error.hpp"
typedef struct {
bool_t running;
int32_t argc;
const char_t **argv;
} engine_t;
extern engine_t ENGINE;
/**
* Initializes the engine.
*
* @param argc The argument count from main().
* @param argv The argument vector from main().
*/
errorret_t engineInit(const int32_t argc, const char_t **argv);
/**
* Updates the engine.
*/
errorret_t engineUpdate(void);
/**
* Shuts down the engine.
*/
errorret_t engineDispose(void);

View File

@@ -1,10 +0,0 @@
# Copyright (c) 2025 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
error.cpp
)

View File

@@ -1,133 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assert/assert.hpp"
#include "error.hpp"
#include "util/memory.hpp"
#include "util/string.hpp"
#include "debug/debug.hpp"
errorstate_t ERROR_STATE = { 0 };
errorret_t errorThrowImpl(
errorstate_t *state,
errorcode_t code,
const char_t *file,
const char_t *function,
const int32_t line,
const char_t *message,
...
) {
assertNotNull(state, "Error state cannot be NULL");
assertTrue(code != ERROR_OK, "Error code must not be OK");
assertNotNull(file, "File cannot be NULL");
assertNotNull(function, "Function cannot be NULL");
assertTrue(line >= 0, "File pointer must be valid");
assertNotNull(message, "Message cannot be NULL");
memoryZero(state, sizeof(errorstate_t));
state->code = code;
// Format args.
va_list args;
va_start(args, message);
// Get length of formatted message
va_list argsCopy;
va_copy(argsCopy, args);
int32_t len = stringFormatVA(NULL, 0, message, argsCopy);
va_end(argsCopy);
// Create string to hold the formatted message
state->message = (char_t *)memoryAllocate(len + 1);
stringFormatVA(state->message, len + 1, message, args);
va_end(args);
// Format lines
len = stringFormat(NULL, 0, ERROR_LINE_FORMAT, file, line, function);
assertTrue(len >= 0, "Line formatting failed");
state->lines = (char_t *)memoryAllocate(len + 1);
stringFormat(state->lines, len + 1, ERROR_LINE_FORMAT, file, line, function);
return (errorret_t) {
.code = code,
.state = state
};
}
errorret_t errorOkImpl() {
assertTrue(
ERROR_STATE.code == ERROR_OK,
"Global error state is not OK (Likely missing errorCatch)"
);
return (errorret_t) {
.code = ERROR_OK,
.state = NULL
};
}
errorret_t errorChainImpl(
const errorret_t retval,
const char_t *file,
const char_t *function,
const int32_t line
) {
if(retval.code == ERROR_OK) return retval;
assertNotNull(retval.state, "Error state NULL (Likely missing errorOk)");
assertNotNull(retval.state->message, "Message cannot be NULL");
// Create a new line string.
int32_t newLineLen = snprintf(NULL, 0, ERROR_LINE_FORMAT, file, line, function);
assertTrue(newLineLen >= 0, "Line formatting failed");
char_t *newLine = (char_t *)memoryAllocate(newLineLen + 1);
snprintf(newLine, newLineLen + 1, ERROR_LINE_FORMAT, file, line, function);
// Resize the existing lines to accommodate the new line
size_t existingLen = strlen(retval.state->lines);
memoryResize(
(void**)&retval.state->lines,
existingLen,
existingLen + newLineLen + 1
);
// Now append the new line to the existing lines
memoryCopy(
retval.state->lines + existingLen,
newLine,
newLineLen + 1
);
// Cleanup the temporary new line
memoryFree(newLine);
return retval;
}
void errorCatch(const errorret_t retval) {
if(retval.code == ERROR_OK) return;
assertNotNull(retval.state, "Error state cannot be NULL");
assertNotNull(retval.state->message, "Message cannot be NULL");
memoryFree((void*)retval.state->message);
}
errorret_t errorPrint(const errorret_t retval) {
if(retval.code == ERROR_OK) return retval;
assertNotNull(retval.state, "Error state cannot be NULL");
assertNotNull(retval.state->message, "Message cannot be NULL");
debugPrint(
ERROR_PRINT_FORMAT,
retval.state->code,
retval.state->message,
retval.state->lines
);
return retval;
}

View File

@@ -1,165 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.hpp"
typedef uint8_t errorcode_t;
typedef struct {
errorcode_t code;
char_t *message;
char_t *lines;
} errorstate_t;
typedef struct {
errorcode_t code;
errorstate_t *state;
} errorret_t;
static const errorcode_t ERROR_OK = 0;
static const errorcode_t ERROR_NOT_OK = 1;
static const char_t *ERROR_PRINT_FORMAT = "Error (%d): %s\n%s";
static const char_t *ERROR_LINE_FORMAT = " at %s:%d in function %s\n";
extern errorstate_t ERROR_STATE;
/**
* Sets the error state with the provided code and message.
*
* @param state The error state to initialize.
* @param code The error code to set.
* @param file The file where the error occurred.
* @param function The function where the error occurred.
* @param line The line number where the error occurred.
* @param message The error message.
* @param args The arguments for the error message.
* @return The error code.
*/
errorret_t errorThrowImpl(
errorstate_t *state,
errorcode_t code,
const char_t *file,
const char_t *function,
const int32_t line,
const char_t *message,
...
);
/**
* Returns an error state with no error.
*
* @return An error state with code ERROR_OK.
*/
errorret_t errorOkImpl();
/**
* Chains an error state, allowing for error propagation.
*
* @param retval The return value containing the error state.
* @param file The file where the error occurred.
* @param function The function where the error occurred.
* @param line The line number where the error occurred.
* @return The error code if an error occurred, otherwise continues execution.
*/
errorret_t errorChainImpl(
const errorret_t retval,
const char_t *file,
const char_t *function,
const int32_t line
);
/**
* Catches an error and handles it.
*
* @param retval The return value containing the error state.
*/
void errorCatch(const errorret_t retval);
/**
* Prints the error state to the console.
*
* @param retval The return value containing the error state.
* @return Passed retval for chaining.
*/
errorret_t errorPrint(const errorret_t retval);
/**
* Creates an error with a specific error state.
*
* @param state The error state to set.
* @param message The format string for the error message.
* @param ... Additional arguments for the format string.
* @return The error code.
*/
#define errorCreate(state, message, ... ) \
errorThrowImpl(\
(state), ERROR_NOT_OK, __FILE__, __func__, __LINE__, (message), \
##__VA_ARGS__ \
)
/**
* Throws an error with a specific error state.
*
* @param state The error state to set.
* @param message The format string for the error message.
* @param ... Additional arguments for the format string.
* @return The error code.
*/
#define errorThrowState(state, message, ... ) \
return errorThrowImpl(\
(state), ERROR_NOT_OK, __FILE__, __func__, __LINE__, (message), \
##__VA_ARGS__ \
)
/**
* Throws an error with a formatted message.
*
* @param code The error code to throw.
* @param message The format string for the error message.
* @param ... Additional arguments for the format string.
* @return The error code.
*/
#define errorThrowWithCode(code, message, ... ) \
return errorThrowImpl(\
&ERROR_STATE, (code), __FILE__, __func__, __LINE__, (message), \
__VA_ARGS__ \
)
/**
* Throws an error with a default error code of ERROR_NOT_OK.
*
* @param message The format string for the error message.
* @param ... Additional arguments for the format string.
* @return The error code.
*/
#define errorThrow(message, ...) \
return errorThrowImpl(\
&ERROR_STATE, ERROR_NOT_OK, __FILE__, __func__, __LINE__, (message), \
##__VA_ARGS__ \
)
/**
* Checks if a child method errored, and if it did, then send it up the chain.
* @param retval The return value containing the error state.
* @return The error code if an error occurred, otherwise continues execution.
*/
#define errorChain(retval) { \
errorret_t errorChainRetval = (retval); \
if(errorChainRetval.code != ERROR_OK) { \
return errorChainImpl(errorChainRetval, __FILE__, __func__, __LINE__); \
} \
}
/**
* Returns without an error.
*/
#define errorOk() \
return errorOkImpl()
// EOF

View File

@@ -12,13 +12,12 @@
localemanager_t LOCALE;
errorret_t localeManagerInit() {
void localeManagerInit() {
memoryZero(&LOCALE, sizeof(localemanager_t));
errorChain(localeManagerSetLocale(DUSK_LOCALE_EN_US));
errorOk();
localeManagerSetLocale(DUSK_LOCALE_EN_US);
}
errorret_t localeManagerSetLocale(const dusklocale_t locale) {
void localeManagerSetLocale(const dusklocale_t locale) {
assertTrue(locale < DUSK_LOCALE_COUNT, "Invalid locale.");
LOCALE.locale = locale;
char_t languageFile[FILENAME_MAX];
@@ -27,8 +26,7 @@ errorret_t localeManagerSetLocale(const dusklocale_t locale) {
);
assetLanguageDispose(&LOCALE.language);
memoryZero(&LOCALE.language, sizeof(assetlanguage_t));
errorChain(assetLoad(languageFile, &LOCALE.language));
errorOk();
assetLoad(languageFile, &LOCALE.language);
}
void localeManagerDispose() {

View File

@@ -35,17 +35,17 @@ extern localemanager_t LOCALE;
/**
* Initialize the locale system.
*
* @return An error code if a failure occurs.
* @throws std::runtime_error if initialization fails.
*/
errorret_t localeManagerInit();
void localeManagerInit();
/**
* Set the current locale.
*
* @param locale The locale to set.
* @return An error code if a failure occurs.
* @throws std::runtime_error if setting the locale fails.
*/
errorret_t localeManagerSetLocale(const dusklocale_t locale);
void localeManagerSetLocale(const dusklocale_t locale);
/**
* Dispose of the locale system.

View File

@@ -5,35 +5,34 @@
* https://opensource.org/licenses/MIT
*/
#include "engine/engine.hpp"
#include "asset/asset.hpp"
#include "util/string.hpp"
#include "input/input.hpp"
#include "engine/Engine.hpp"
using namespace Dusk;
int main(int argc, char **argv) {
// Main applet
errorret_t ret;
// Init engine
ret = engineInit(argc, (const char_t **)argv);
if(ret.code != ERROR_OK) {
errorCatch(errorPrint(ret));
return ret.code;
try {
Engine::ENGINE.init(argc, (const char_t **)argv);
} catch (const std::runtime_error &e) {
std::fprintf(stderr, "Fatal error during engine initialization: %s\n", e.what());
return 1;
}
// Begin main loop
try {
do {
ret = engineUpdate();
if(ret.code != ERROR_OK) {
errorCatch(errorPrint(ret));
return ret.code;
Engine::ENGINE.update();
} while(Engine::ENGINE.isRunning());
} catch (const std::runtime_error &e) {
std::fprintf(stderr, "Fatal error during engine update: %s\n", e.what());
return 1;
}
} while(ENGINE.running);
ret = engineDispose();
if(ret.code != ERROR_OK) {
errorCatch(errorPrint(ret));
return ret.code;
try {
Engine::ENGINE.exit();
} catch (const std::runtime_error &e) {
std::fprintf(stderr, "Fatal error during engine exit: %s\n", e.what());
return 1;
}
return 0;

View File

@@ -15,13 +15,13 @@
#include "util/memory.hpp"
#include "assert/assert.hpp"
errorret_t rpgInit(void) {
void rpgInit(void) {
memoryZero(ENTITIES, sizeof(ENTITIES));
// Init cutscene subsystem
cutsceneSystemInit();
errorChain(mapInit());
mapInit();
rpgCameraInit();
rpgTextboxInit();
@@ -34,16 +34,11 @@ errorret_t rpgInit(void) {
// RPG_CAMERA.mode = RPG_CAMERA_MODE_FOLLOW_ENTITY;
// RPG_CAMERA.followEntity.followEntityId = ent->id;
// ent->position.x = 2, ent->position.y = 2;
// All Good!
errorOk();
}
errorret_t rpgUpdate(void) {
void rpgUpdate(void) {
#if TIME_FIXED == 0
if(TIME.dynamicUpdate) {
errorOk();
}
if(TIME.dynamicUpdate) return;
#endif
// TODO: Do not update if the scene is not the map scene?
@@ -57,8 +52,7 @@ errorret_t rpgUpdate(void) {
} while(++ent < &ENTITIES[ENTITY_COUNT]);
cutsceneSystemUpdate();
errorChain(rpgCameraUpdate());
errorOk();
rpgCameraUpdate();
}
void rpgDispose(void) {

View File

@@ -6,7 +6,7 @@
*/
#pragma once
#include "error/error.hpp"
#include "dusk.hpp"
typedef struct {
int32_t nothing;
@@ -17,14 +17,14 @@ typedef struct {
*
* @return An error code and state.
*/
errorret_t rpgInit(void);
void rpgInit(void);
/**
* Update the RPG subsystem.
*
* @return An error code.
*/
errorret_t rpgUpdate(void);
void rpgUpdate(void);
/**
* Dispose of the RPG subsystem.

View File

@@ -17,7 +17,7 @@ void rpgCameraInit(void) {
memoryZero(&RPG_CAMERA, sizeof(rpgcamera_t));
}
errorret_t rpgCameraUpdate(void) {
void rpgCameraUpdate(void) {
chunkpos_t chunkPos;
switch(RPG_CAMERA.mode) {
@@ -27,9 +27,7 @@ errorret_t rpgCameraUpdate(void) {
case RPG_CAMERA_MODE_FOLLOW_ENTITY: {
entity_t *entity = &ENTITIES[RPG_CAMERA.followEntity.followEntityId];
if(entity->type == ENTITY_TYPE_NULL) {
errorOk();
}
if(entity->type == ENTITY_TYPE_NULL) return;
// Update map position to match camera. By default map wants to know the
// top left but we want to set the center, so we need to sub half map size
@@ -41,10 +39,9 @@ errorret_t rpgCameraUpdate(void) {
assertUnreachable("Invalid RPG camera mode");
}
errorChain(mapPositionSet((chunkpos_t){
mapPositionSet((chunkpos_t){
.x = chunkPos.x - (MAP_CHUNK_WIDTH / 2),
.y = chunkPos.y - (MAP_CHUNK_HEIGHT / 2),
.z = chunkPos.z - (MAP_CHUNK_DEPTH / 2)
}));
errorOk();
});
}

View File

@@ -7,7 +7,6 @@
#pragma once
#include "rpg/world/worldpos.hpp"
#include "error/error.hpp"
typedef enum {
RPG_CAMERA_MODE_FREE,
@@ -35,6 +34,6 @@ void rpgCameraInit(void);
/**
* Updates the RPG camera.
*
* @return An error code.
* @throws std::runtime_error if map position setting fails.
*/
errorret_t rpgCameraUpdate(void);
void rpgCameraUpdate(void);

View File

@@ -13,7 +13,7 @@
map_t MAP;
errorret_t mapInit() {
void mapInit() {
memoryZero(&MAP, sizeof(map_t));
// Init the default chunks. In future I'll probably make this based on where
@@ -27,20 +27,16 @@ errorret_t mapInit() {
chunk->position.y = y;
chunk->position.z = z;
MAP.chunkOrder[index] = chunk;
errorChain(mapChunkLoad(chunk));
mapChunkLoad(chunk);
index++;
}
}
}
errorOk();
}
errorret_t mapPositionSet(const chunkpos_t newPos) {
void mapPositionSet(const chunkpos_t newPos) {
const chunkpos_t curPos = MAP.chunkPosition;
if(chunkPositionIsEqual(curPos, newPos)) {
errorOk();
}
if(chunkPositionIsEqual(curPos, newPos)) return;
// Determine which chunks remain loaded
chunkindex_t chunksRemaining[MAP_CHUNK_COUNT] = {0};
@@ -102,7 +98,7 @@ errorret_t mapPositionSet(const chunkpos_t newPos) {
chunkIndex = chunksFreed[--freedCount];
chunk_t *chunk = &MAP.chunks[chunkIndex];
chunk->position = newChunkPos;
errorChain(mapChunkLoad(chunk));
mapChunkLoad(chunk);
}
MAP.chunkOrder[orderIndex++] = &MAP.chunks[chunkIndex];
@@ -112,8 +108,6 @@ errorret_t mapPositionSet(const chunkpos_t newPos) {
// Update map position
MAP.chunkPosition = newPos;
errorOk();
}
void mapUpdate() {
@@ -138,7 +132,7 @@ void mapChunkUnload(chunk_t* chunk) {
}
}
errorret_t mapChunkLoad(chunk_t* chunk) {
void mapChunkLoad(chunk_t* chunk) {
char_t buffer[64];
chunk->meshCount = 0;
@@ -153,11 +147,10 @@ errorret_t mapChunkLoad(chunk_t* chunk) {
if(!assetFileExists(buffer)) {
memoryZero(chunk->tiles, sizeof(chunk->tiles));
errorOk();
return;
}
errorChain(assetLoad(buffer, chunk));
errorOk();
assetLoad(buffer, chunk);
}
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {

View File

@@ -19,9 +19,9 @@ extern map_t MAP;
/**
* Initializes the map.
*
* @return An error code.
* @throws std::runtime_error if chunk loading fails.
*/
errorret_t mapInit();
void mapInit();
/**
* Updates the map.
@@ -37,9 +37,9 @@ void mapDispose();
* Sets the map position and updates chunks accordingly.
*
* @param newPos The new chunk position.
* @return An error code.
* @throws std::runtime_error if chunk loading fails.
*/
errorret_t mapPositionSet(const chunkpos_t newPos);
void mapPositionSet(const chunkpos_t newPos);
/**
* Unloads a chunk.
@@ -52,9 +52,9 @@ void mapChunkUnload(chunk_t* chunk);
* Loads a chunk.
*
* @param chunk The chunk to load.
* @return An error code.
* @throws std::runtime_error if chunk loading fails.
*/
errorret_t mapChunkLoad(chunk_t* chunk);
void mapChunkLoad(chunk_t* chunk);
/**
* Gets the index of a chunk, within the world, at the given position.

View File

@@ -7,7 +7,6 @@
#pragma once
#include "dusk.hpp"
#include "error/error.hpp"
#include "display/color.hpp"
#define SCENE_FLAG_INITIALIZED (1 << 0)
@@ -16,7 +15,7 @@ typedef struct scenedata_s scenedata_t;
typedef struct {
const char_t *name;
errorret_t (*init)(scenedata_t *data);
void (*init)(scenedata_t *data);
void (*update)(scenedata_t *data);
void (*render)(scenedata_t *data);
void (*dispose)(scenedata_t *data);

View File

@@ -17,7 +17,7 @@
#include "util/memory.hpp"
#include "duskdefs.hpp"
errorret_t sceneMapInit(scenedata_t *data) {
void sceneMapInit(scenedata_t *data) {
// Init the camera.
cameraInitPerspective(&data->sceneMap.camera);
data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED;
@@ -36,8 +36,6 @@ errorret_t sceneMapInit(scenedata_t *data) {
RPG_CAMERA_PIXELS_PER_UNIT
);
data->sceneMap.camera.perspective.fov = glm_rad(RPG_CAMERA_FOV);
errorOk();
}
void sceneMapUpdate(scenedata_t *data) {

View File

@@ -15,7 +15,7 @@ typedef struct {
camera_t camera;
} scenemap_t;
errorret_t sceneMapInit(scenedata_t *data);
void sceneMapInit(scenedata_t *data);
void sceneMapUpdate(scenedata_t *data);
void sceneMapRender(scenedata_t *data);
void sceneMapRenderEntity(entity_t *entity);

View File

@@ -8,9 +8,8 @@
#include "scenetest.hpp"
#include "scene/scenedata.hpp"
errorret_t sceneTestInit(scenedata_t *data) {
void sceneTestInit(scenedata_t *data) {
data->sceneTest.nothing = 0;
errorOk();
}
void sceneTestUpdate(scenedata_t *data) {

View File

@@ -12,7 +12,7 @@ typedef struct {
int32_t nothing;
} scenetest_t;
errorret_t sceneTestInit(scenedata_t *data);
void sceneTestInit(scenedata_t *data);
void sceneTestUpdate(scenedata_t *data);
void sceneTestRender(scenedata_t *data);
void sceneTestDispose(scenedata_t *data);

View File

@@ -13,7 +13,7 @@
scenemanager_t SCENE_MANAGER;
errorret_t sceneManagerInit(void) {
void sceneManagerInit(void) {
memoryZero(&SCENE_MANAGER, sizeof(scenemanager_t));
sceneManagerRegisterScene(&SCENE_TEST);
@@ -22,10 +22,8 @@ errorret_t sceneManagerInit(void) {
// Initial scene
scene_t *initial = sceneManagerGetSceneByName("map");
sceneManagerSetScene(initial);
if(initial->init) errorChain(initial->init(&SCENE_MANAGER.sceneData));
if(initial->init) initial->init(&SCENE_MANAGER.sceneData);
initial->flags |= SCENE_FLAG_INITIALIZED;
errorOk();
}
scene_t * sceneManagerGetSceneByName(const char_t *name) {

View File

@@ -23,7 +23,7 @@ extern scenemanager_t SCENE_MANAGER;
/**
* Initializes the scene manager and the initial scene.
*/
errorret_t sceneManagerInit(void);
void sceneManagerInit(void);
/**
* Retrieves a registered scene by its name.

View File

@@ -15,7 +15,7 @@
#include "script/func/scriptfuncentity.hpp"
#include "script/func/scriptfuncsystem.hpp"
errorret_t scriptContextInit(scriptcontext_t *context) {
void scriptContextInit(scriptcontext_t *context) {
assertNotNull(context, "Script context cannot be NULL");
memoryZero(context, sizeof(scriptcontext_t));
@@ -23,15 +23,13 @@ errorret_t scriptContextInit(scriptcontext_t *context) {
// Create a new Lua state for this context.
context->luaState = luaL_newstate();
if(context->luaState == NULL) {
errorThrow("Failed to init Lua state");
throw std::runtime_error("Failed to init Lua state");
}
luaL_openlibs(context->luaState);
// Register functions
scriptFuncSystem(context);
scriptFuncEntity(context);
errorOk();
}
void scriptContextRegFunc(
@@ -46,7 +44,7 @@ void scriptContextRegFunc(
lua_register(context->luaState, fnName, function);
}
errorret_t scriptContextCallFunc(
void scriptContextCallFunc(
scriptcontext_t *context,
const char_t *fnName,
const scriptvalue_t *args,
@@ -60,7 +58,9 @@ errorret_t scriptContextCallFunc(
// Get func
lua_getglobal(context->luaState, fnName);
if(!lua_isfunction(context->luaState, -1)) {
errorThrow("Function '%s' not found in script context", fnName);
throw std::runtime_error(
"Function '" + std::string(fnName) + "' not found in script context"
);
}
// Push args
@@ -80,7 +80,9 @@ errorret_t scriptContextCallFunc(
break;
default:
errorThrow("Unsupported argument type %d", arg->type);
throw std::runtime_error(
"Unsupported argument type " + std::to_string(arg->type)
);
}
}
@@ -93,33 +95,48 @@ errorret_t scriptContextCallFunc(
) != LUA_OK) {
const char_t *strErr = lua_tostring(context->luaState, -1);
lua_pop(context->luaState, 1);
errorThrow("Failed to call function '%s': %s", fnName, strErr);
throw std::runtime_error(
"Failed to call Lua function '" +
std::string(fnName) +
"': " +
std::string(strErr)
);
}
// Was there a ret value?
if(retValue == NULL) {
errorOk();
}
if(retValue == NULL) return;
// Get ret value
switch(retValue->type) {
case SCRIPT_VALUE_TYPE_INT:
if(!lua_isinteger(context->luaState, -1)) {
errorThrow("Expected integer return value from '%s'", fnName);
throw std::runtime_error(
"Expected integer return value from '" +
std::string(fnName) +
"'"
);
}
retValue->value.intValue = (int32_t)lua_tointeger(context->luaState, -1);
break;
case SCRIPT_VALUE_TYPE_FLOAT:
if(!lua_isnumber(context->luaState, -1)) {
errorThrow("Expected float return value from '%s'", fnName);
throw std::runtime_error(
"Expected float return value from '" +
std::string(fnName) +
"'"
);
}
retValue->value.floatValue = (float)lua_tonumber(context->luaState, -1);
break;
case SCRIPT_VALUE_TYPE_BOOL:
if(!lua_isboolean(context->luaState, -1)) {
errorThrow("Expected boolean return value from '%s'", fnName);
throw std::runtime_error(
"Expected boolean return value from '" +
std::string(fnName) +
"'"
);
}
retValue->value.boolValue = lua_toboolean(context->luaState, -1);
break;
@@ -132,48 +149,49 @@ errorret_t scriptContextCallFunc(
// break;
default:
errorThrow("Unsupported return value type %d", retValue->type);
throw std::runtime_error(
"Unsupported return value type " + std::to_string(retValue->type)
);
}
}
errorOk();
}
errorret_t scriptContextExec(scriptcontext_t *context, const char_t *script) {
void scriptContextExec(scriptcontext_t *context, const char_t *script) {
assertNotNull(context, "Script context cannot be NULL");
assertNotNull(script, "Script cannot be NULL");
if(luaL_dostring(context->luaState, script) != LUA_OK) {
const char_t *strErr = lua_tostring(context->luaState, -1);
lua_pop(context->luaState, 1);
errorThrow("Failed to execute Lua: ", strErr);
throw std::runtime_error("Failed to execute Lua: " + std::string(strErr));
}
}
errorOk();
}
errorret_t scriptContextExecFile(scriptcontext_t *ctx, const char_t *fname) {
void scriptContextExecFile(scriptcontext_t *ctx, const char_t *fname) {
assertNotNull(ctx, "Script context cannot be NULL");
assertNotNull(fname, "Filename cannot be NULL");
assetscript_t script;
errorChain(assetLoad(fname, &script));
assetLoad(fname, &script);
if(lua_load(
ctx->luaState, assetScriptReader, &script, fname, NULL
) != LUA_OK) {
const char_t *strErr = lua_tostring(ctx->luaState, -1);
lua_pop(ctx->luaState, 1);
errorThrow("Failed to load Lua script: %s", strErr);
throw std::runtime_error(
"Failed to load Lua script: " + std::string(strErr)
);
}
if(lua_pcall(ctx->luaState, 0, LUA_MULTRET, 0) != LUA_OK) {
const char_t *strErr = lua_tostring(ctx->luaState, -1);
lua_pop(ctx->luaState, 1);
errorThrow("Failed to execute Lua script: %s", strErr);
throw std::runtime_error(
"Failed to execute Lua script: " + std::string(strErr)
);
}
errorChain(assetScriptDispose(&script));
errorOk();
assetScriptDispose(&script);
}
void scriptContextDispose(scriptcontext_t *context) {

View File

@@ -6,7 +6,6 @@
*/
#pragma once
#include "error/error.hpp"
#include "scriptvalue.hpp"
extern "C" {
@@ -23,9 +22,9 @@ typedef struct scriptcontext_s {
* Initialize a script context.
*
* @param context The script context to initialize.
* @return The error return value.
* @throws std::runtime_error on failure.
*/
errorret_t scriptContextInit(scriptcontext_t *context);
void scriptContextInit(scriptcontext_t *context);
/**
* Register a C function within a script context.
@@ -48,10 +47,10 @@ void scriptContextRegFunc(
* @param args Array of args to pass to the function (or NULL for no args)
* @param argCount The number of arguments in the args array (omitable).
* @param retValue Output to store returned value (or NULL for no return value).
* @return The error return value.
* @throws std::runtime_error on failure.
*/
errorret_t scriptContextCallFunc(
void scriptContextCallFunc(
scriptcontext_t *context,
const char_t *fnName,
const scriptvalue_t *args,
@@ -64,18 +63,18 @@ errorret_t scriptContextCallFunc(
*
* @param context The script context to use.
* @param script The script to execute.
* @return The error return value.
* @throws std::runtime_error on failure.
*/
errorret_t scriptContextExec(scriptcontext_t *context, const char_t *script);
void scriptContextExec(scriptcontext_t *context, const char_t *script);
/**
* Execute a script from a file within a script context.
*
* @param ctx The script context to use.
* @param fname The filename of the script to execute.
* @return The error return value.
* @throws std::runtime_error on failure.
*/
errorret_t scriptContextExecFile(scriptcontext_t *ctx, const char_t *fname);
void scriptContextExecFile(scriptcontext_t *ctx, const char_t *fname);
/**
* Dispose of a script context.

View File

@@ -13,11 +13,9 @@
scriptmanager_t SCRIPT_MANAGER;
errorret_t scriptManagerInit() {
void scriptManagerInit() {
memoryZero(&SCRIPT_MANAGER, sizeof(scriptmanager_t));
errorOk();
}
errorret_t scriptManagerDispose() {
errorOk();
void scriptManagerDispose() {
}

View File

@@ -6,7 +6,6 @@
*/
#pragma once
#include "error/error.hpp"
#include "scriptcontext.hpp"
typedef struct scriptmanager_s {
@@ -18,13 +17,13 @@ extern scriptmanager_t SCRIPT_MANAGER;
/**
* Initialize the script manager.
*
* @return The error return value.
* @throws Any exceptions if initialization fails.
*/
errorret_t scriptManagerInit();
void scriptManagerInit();
/**
* Dispose of the script manager.
*
* @return The error return value.
* @throws Any exceptions if disposal fails.
*/
errorret_t scriptManagerDispose();
void scriptManagerDispose();

View File

@@ -15,15 +15,13 @@
ui_t UI;
errorret_t uiInit(void) {
void uiInit(void) {
memoryZero(&UI, sizeof(ui_t));
cameraInitOrthographic(&UI.camera);
// Initialize UI components here
uiSetFont(&TILESET_MINOGRAM);
errorOk();
}
void uiUpdate(void) {
@@ -47,7 +45,7 @@ void uiRender(void) {
cameraPopMatrix();
}
errorret_t uiSetFont(const tileset_t *fontTileset) {
void uiSetFont(const tileset_t *fontTileset) {
if(UI.fontTexture.width > 0) {
textureDispose(&UI.fontTexture);
UI.fontTexture.width = -1;
@@ -56,8 +54,7 @@ errorret_t uiSetFont(const tileset_t *fontTileset) {
assertNotNull(fontTileset, "Font tileset cannot be NULL.");
UI.fontTileset = fontTileset;
errorChain(assetLoad(UI.fontTileset->image, &UI.fontTexture));
errorOk();
assetLoad(UI.fontTileset->image, &UI.fontTexture);
}
void uiDispose(void) {

View File

@@ -22,9 +22,9 @@ extern ui_t UI;
/**
* Initializes the UI system, loading necessary resources.
*
* @return An errorret_t indicating success or failure.
* @throws Any exceptions if initialization fails.
*/
errorret_t uiInit(void);
void uiInit(void);
/**
* Updates the UI state, handling user interactions and animations.
@@ -40,10 +40,9 @@ void uiRender(void);
* Sets the font tileset for UI text rendering.
*
* @param fontTileset Pointer to the tileset to use for UI fonts.
*
* @return An errorret_t indicating success or failure.
* @throws Any exceptions if setting the font fails.
*/
errorret_t uiSetFont(const tileset_t *fontTileset);
void uiSetFont(const tileset_t *fontTileset);
/**
* Cleans up and frees all UI resources.