diff --git a/src/asset/CMakeLists.txt b/src/asset/CMakeLists.txt index 29b4dbc..75531bb 100644 --- a/src/asset/CMakeLists.txt +++ b/src/asset/CMakeLists.txt @@ -6,5 +6,6 @@ # Sources target_sources(${DUSK_TARGET_NAME} PRIVATE + asset.c assetmanager.c ) \ No newline at end of file diff --git a/src/asset/asset.c b/src/asset/asset.c new file mode 100644 index 0000000..409fe32 --- /dev/null +++ b/src/asset/asset.c @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2025 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#include "asset.h" +#include "assetmanager.h" +#include "util/memory.h" +#include "assert/assert.h" +#include "console/console.h" + +errorret_t assetInit(asset_t *asset, const char_t *filename) { + assertNotNull(asset, "Asset cannot be NULL."); + assertNotNull(filename, "Filename cannot be NULL."); + assertTrue(strlen(filename) < FILENAME_MAX, "Filename too long."); + assertTrue(strlen(filename) > 0, "Filename cannot be empty."); + + memoryZero(asset, sizeof(asset_t)); + memoryCopy(asset->filename, filename, strlen(filename) + 1); + + // Initialze the reference list. + refListInit( + &asset->refList, + asset->refListArray, + ASSET_REFERENCE_COUNT_MAX + ); + + asset->file = zip_fopen(ASSET_MANAGER.zip, filename, 0); + if(asset->file == NULL) errorThrow("Failed to open asset file: %s", filename); + + consolePrint("Initialized asset: %s", filename); + + errorOk(); +} \ No newline at end of file diff --git a/src/asset/asset.h b/src/asset/asset.h index f529c6f..d98c71a 100644 --- a/src/asset/asset.h +++ b/src/asset/asset.h @@ -7,7 +7,9 @@ #pragma once #include "assetpaletteimage.h" +#include "error/error.h" #include "util/reflist.h" +#include #define ASSET_HEADER_SIZE 3 #define ASSET_REFERENCE_COUNT_MAX 8 @@ -31,4 +33,15 @@ typedef struct { assetstate_t state; assettype_t type; void *data; -} asset_t; \ No newline at end of file + zip_file_t *file; +} asset_t; + +/** + * Initializes an asset structure. This should be called by the asset manager + * only. + * + * @param asset The asset structure to initialize. + * @param filename The filename of the asset. + * @return An error code. + */ +errorret_t assetInit(asset_t *asset, const char_t *filename); \ No newline at end of file diff --git a/src/asset/assetmanager.c b/src/asset/assetmanager.c index 893b915..29cb08b 100644 --- a/src/asset/assetmanager.c +++ b/src/asset/assetmanager.c @@ -43,6 +43,38 @@ errorret_t assetManagerInit(void) { errorOk(); } +void assetManagerUpdate(void) { + +} + +errorret_t assetManagerGetAsset(const char_t *filename, asset_t **outAsset) { + assertNotNull(outAsset, "Output asset pointer cannot be null."); + assertNotNull(filename, "Filename cannot be null."); + assertStrLenMin(filename, 1, "Filename cannot be empty."); + assertStrLenMax(filename, FILENAME_MAX - 1, "Filename is too long."); + + // Is this asset already in memory? + asset_t *asset = ASSET_MANAGER.assets; + while(asset < &ASSET_MANAGER.assets[ASSET_MANAGER.assetCount]) { + if(stringCompare(asset->filename, filename) == 0) { + *outAsset = asset; + errorOk(); + } + ++asset; + } + + // Asset not in memory, can we load it? + if(ASSET_MANAGER.assetCount >= ASSET_MANAGER_ASSET_COUNT_MAX) { + *outAsset = NULL; + errorThrow("Asset limit reached."); + } + + // Pop an asset off the struct + asset = &ASSET_MANAGER.assets[ASSET_MANAGER.assetCount++]; + errorChain(assetInit(asset, filename)); + errorOk(); +} + void assetManagerDispose(void) { if(ASSET_MANAGER.zip != NULL) { zip_close(ASSET_MANAGER.zip); diff --git a/src/asset/assetmanager.h b/src/asset/assetmanager.h index cb527ec..c79bcbc 100644 --- a/src/asset/assetmanager.h +++ b/src/asset/assetmanager.h @@ -6,8 +6,6 @@ */ #pragma once -#include "error/error.h" -#include #include "display/texture/texture.h" #include "asset.h" @@ -46,22 +44,19 @@ extern assetmanager_t ASSET_MANAGER; errorret_t assetManagerInit(void); /** - * Gets and requests a lock on a given asset. Locking an asset will prevent it - * from being unloaded until it is unlocked. - * - * @param filename The filename of the asset to lock. - * @param outRef A pointer to store the locked reference ID in. - * @return A pointer to the locked asset, or NULL if the asset could not be + * Update the asset manager. This should be called once per frame. */ -asset_t * assetManagerLock(const char_t *filename, ref_t *outRef); +void assetManagerUpdate(void); /** - * Unlocks a previously locked asset reference. + * Get an asset by filename. This will return NULL if the asset does not exist. + * This will not lock the asset, you must do that separately. * - * @param asset The asset to unlock the reference from. - * @param ref The reference ID to unlock. + * @param filename The filename of the asset to get. + * @param outAsset The output asset pointer. + * @return An error code. */ -void assetManagerUnlock(const ref_t ref); +errorret_t assetManagerGetAsset(const char_t *filename, asset_t **outAsset); /** * Disposes/cleans up the asset system. diff --git a/src/console/console.h b/src/console/console.h index 64d9462..b94a5c5 100644 --- a/src/console/console.h +++ b/src/console/console.h @@ -94,10 +94,9 @@ consolevar_t * consoleRegVar( consolevar_t * consoleVarGet(const char_t *name); /** - * Sets the value of a console variable. + * Prints a message to the console. * - * @param name The name of the variable. - * @param value The new value of the variable. + * @param message The message to print. */ void consolePrint( const char_t *message, diff --git a/src/engine/engine.c b/src/engine/engine.c index 6e214f5..7951623 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -15,6 +15,8 @@ engine_t ENGINE; +asset_t *testAsset; + errorret_t engineInit(void) { memoryZero(&ENGINE, sizeof(engine_t)); ENGINE.running = true; @@ -26,12 +28,15 @@ errorret_t engineInit(void) { errorChain(displayInit()); rpgInit(); + errorChain(assetManagerGetAsset("entities.dpi", &testAsset)); + errorOk(); } errorret_t engineUpdate(void) { timeUpdate(); consoleUpdate(); + assetManagerUpdate(); errorChain(displayUpdate()); errorOk(); diff --git a/src/error/error.h b/src/error/error.h index 0fd3f7f..ebefd2c 100644 --- a/src/error/error.h +++ b/src/error/error.h @@ -151,10 +151,13 @@ errorret_t errorPrint(const errorret_t retval); * @param retval The return value containing the error state. * @return The error code if an error occurred, otherwise continues execution. */ -#define errorChain(retval) \ - if ((retval).code != ERROR_OK) { \ - return errorChainImpl(retval, __FILE__, __func__, __LINE__); \ - } +#define errorChain(retval) { \ + errorret_t errorChainRetval = (retval); \ + if (errorChainRetval.code != ERROR_OK) { \ + return errorChainImpl(errorChainRetval, __FILE__, __func__, __LINE__); \ + } \ +} + /** * Returns without an error. diff --git a/src/main.c b/src/main.c index 0aa8028..eba3b57 100644 --- a/src/main.c +++ b/src/main.c @@ -15,14 +15,17 @@ int main(int argc, char **argv) { errorret_t ret; ret = engineInit(); - // Set console variable - if(argc > 0) consoleRegVar("sys_path", argv[0], NULL); - if(ret.code != ERROR_OK) { errorCatch(errorPrint(ret)); return ret.code; } + // Set console variable. This is commented out because at the moment; + // Engine init happens, which needs to happen to init console + // It also inits asset manager, and the problem is that asset manager + // needs to know where the sys_path is to find the asset file. + // if(argc > 0) consoleRegVar("sys_path", argv[0], NULL); + do { ret = engineUpdate(); if(ret.code != ERROR_OK) {