/** * Copyright (c) 2025 Dominic Masters * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ #include "assetmanager.h" #include "util/memory.h" #include "util/string.h" #include "assert/assert.h" #define ASSET_ASSET_FILE "dusk.dsk" assetmanager_t ASSET_MANAGER; errorret_t assetManagerInit(void) { memoryZero(&ASSET_MANAGER, sizeof(assetmanager_t)); // Default system path, intended to be overridden by the paltform stringCopy(ASSET_MANAGER.systemPath, ".", FILENAME_MAX); // Open zip file char_t searchPath[FILENAME_MAX]; for(int32_t i = 0; i < ASSET_MANAGER_SEARCH_PATHS_COUNT; i++) { sprintf( searchPath, ASSET_MANAGER_SEARCH_PATHS[i], ASSET_MANAGER.systemPath, ASSET_ASSET_FILE ); // Try open ASSET_MANAGER.zip = zip_open(searchPath, ZIP_RDONLY, NULL); if(ASSET_MANAGER.zip == NULL) continue; break; } // Did we open the asset? if(ASSET_MANAGER.zip == NULL) errorThrow("Failed to open asset file."); errorOk(); } void assetManagerUpdate(void) { // Update all assets asset_t *asset = ASSET_MANAGER.assets; while(asset < &ASSET_MANAGER.assets[ASSET_MANAGER.assetCount]) { if(asset->state == ASSET_STATE_LOADING) { // Check if the asset is loaded if(asset->file != NULL) { asset->state = ASSET_STATE_LOADED; } } ++asset; } } 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++]; *outAsset = asset; errorChain(assetInit(asset, filename)); errorOk(); } errorret_t assetManagerLoadAsset( const char_t *filename, asset_t **outAsset, ref_t *outRef ) { assertNotNull(outRef, "Output reference pointer cannot be null."); errorChain(assetManagerGetAsset(filename, outAsset)); ref_t ref = assetLock(*outAsset); errorChain(assetLoad(*outAsset)); *outRef = ref; errorOk(); } void assetManagerDispose(void) { asset_t *asset = ASSET_MANAGER.assets; while(asset < &ASSET_MANAGER.assets[ASSET_MANAGER.assetCount]) { assetDispose(asset); ++asset; } if(ASSET_MANAGER.zip != NULL) { zip_close(ASSET_MANAGER.zip); ASSET_MANAGER.zip = NULL; } }