Refactor asset loading

This commit is contained in:
2025-11-04 22:23:44 -06:00
parent 7c11a7e5bc
commit 1ce1fdff8d
26 changed files with 198 additions and 1010 deletions

View File

@@ -6,9 +6,8 @@
# Sources
target_sources(${DUSK_TARGET_NAME}
PRIVATE
# asset.c
# assetmanager.c
asset.c
)
# Subdirs
# add_subdirectory(type)
add_subdirectory(type)

View File

@@ -9,22 +9,23 @@
#include "util/memory.h"
#include "util/string.h"
#include "assert/assert.h"
#include "asset/assettype.h"
errorret_t assetInit(void) {
memoryZero(&ASSET_MANAGER, sizeof(assetmanager_t));
// Default system path, intended to be overridden by the paltform
stringCopy(ASSET_MANAGER.systemPath, ".", FILENAME_MAX);
memoryZero(&ASSET, sizeof(asset_t));
// Default system path, intended to be overridden by the platform
stringCopy(ASSET.systemPath, ".", FILENAME_MAX);
// Open zip file
char_t searchPath[FILENAME_MAX];
char_t **path = ASSET_SEARCH_PATHS;
const char_t **path = ASSET_SEARCH_PATHS;
do {
sprintf(
searchPath,
*path,
ASSET_MANAGER.systemPath,
ASSET_ASSET_FILE
ASSET.systemPath,
ASSET_FILE
);
// Try open
@@ -39,13 +40,61 @@ errorret_t assetInit(void) {
errorOk();
}
erroret_t assetLoad(const char_t *filename, void *output) {
errorret_t 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);
}
// Read the header.
assetheader_t header;
memoryZero(&header, sizeof(assetheader_t));
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);
}
// Find the asset type based on the header
const assettypedef_t *def = NULL;
for(uint_fast8_t i = 0; i < ASSET_TYPE_COUNT; i++) {
if(ASSET_TYPE_DEFINITIONS[i].header == NULL) continue;
if(strcmp(header.header, ASSET_TYPE_DEFINITIONS[i].header) != 0) continue;
def = &ASSET_TYPE_DEFINITIONS[i];
break;
}
if(def == NULL) {
zip_fclose(file);
errorThrow("Unknown asset type for file: %s", filename);
}
// We found the asset type, now load the asset data
assertNotNull(def->load, "Asset load function cannot be NULL.");
void *data = memoryAllocate(def->dataSize);
bytesRead = zip_fread(file, data, def->dataSize);
if(bytesRead == 0 || bytesRead > def->dataSize) {
memoryFree(data);
zip_fclose(file);
errorThrow("Failed to read asset data for file: %s", filename);
}
// Close the file now we have the data
zip_fclose(file);
// Pass to the asset type loader
errorret_t ret = def->load(data, output);
memoryFree(data);
errorChain(ret);
errorOk();
}
void assetDispose(void) {
if(ASSET_MANAGER.zip != NULL) {
zip_close(ASSET_MANAGER.zip);
ASSET_MANAGER.zip = NULL;
if(ASSET.zip != NULL) {
zip_close(ASSET.zip);
ASSET.zip = NULL;
}
}

View File

@@ -26,6 +26,12 @@ static const char_t *ASSET_SEARCH_PATHS[] = {
NULL
};
#pragma pack(push, 1)
typedef struct {
char_t header[3];
} assetheader_t;
#pragma pack(pop)
typedef struct {
zip_t *zip;
char_t systemPath[FILENAME_MAX];

41
src/asset/assettype.h Normal file
View File

@@ -0,0 +1,41 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "type/assetpaletteimage.h"
#include "type/assetalphaimage.h"
typedef enum {
ASSET_TYPE_NULL,
ASSET_TYPE_PALETTE_IMAGE,
ASSET_TYPE_ALPHA_IMAGE,
ASSET_TYPE_COUNT,
} assettype_t;
typedef struct {
const char_t *header;
const size_t dataSize;
errorret_t (*load)(void *data, void *output);
} assettypedef_t;
static const assettypedef_t ASSET_TYPE_DEFINITIONS[ASSET_TYPE_COUNT] = {
[ASSET_TYPE_NULL] = {
0
},
[ASSET_TYPE_PALETTE_IMAGE] = {
.header = "DPI",
.dataSize = sizeof(assetpaletteimage_t),
.load = assetPaletteImageLoad
},
[ASSET_TYPE_ALPHA_IMAGE] = {
.header = "DAI",
.dataSize = sizeof(assetalphaimage_t),
.load = assetAlphaImageLoad
},
};

View File

@@ -0,0 +1,11 @@
# 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
assetalphaimage.c
assetpaletteimage.c
)

View File

@@ -0,0 +1,28 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetalphaimage.h"
#include "assert/assert.h"
#include "display/texture.h"
errorret_t assetAlphaImageLoad(void *data, void *output) {
assertNotNull(data, "Data pointer cannot be NULL.");
assertNotNull(output, "Output pointer cannot be NULL.");
assetalphaimage_t *dataPtr = (assetalphaimage_t *)data;
texture_t *outputPtr = (texture_t *)output;
textureInit(
outputPtr,
dataPtr->width,
dataPtr->height,
TEXTURE_FORMAT_ALPHA,
(texturedata_t){ .alpha = { .data = dataPtr->pixels } }
);
errorOk();
}

View File

@@ -0,0 +1,32 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#define ASSET_ALPHA_IMAGE_WIDTH_MAX 256
#define ASSET_ALPHA_IMAGE_HEIGHT_MAX 256
#define ASSET_ALPHA_IMAGE_SIZE_MAX ( \
ASSET_ALPHA_IMAGE_WIDTH_MAX * ASSET_ALPHA_IMAGE_HEIGHT_MAX \
)
#pragma pack(push, 1)
typedef struct {
uint32_t width;
uint32_t height;
uint8_t pixels[ASSET_ALPHA_IMAGE_SIZE_MAX];
} assetalphaimage_t;
#pragma pack(pop)
/**
* Loads an alpha image asset from the given asset structure. The asset must
* 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.
*/
errorret_t assetAlphaImageLoad(void *data, void *output);

View File

@@ -0,0 +1,33 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assetpaletteimage.h"
#include "assert/assert.h"
#include "display/texture.h"
errorret_t assetPaletteImageLoad(void *data, void *output) {
assertNotNull(data, "Data pointer cannot be NULL.");
assertNotNull(output, "Output pointer cannot be NULL.");
assetpaletteimage_t *assetData = (assetpaletteimage_t *)data;
texture_t *texture = (texture_t *)output;
textureInit(
texture,
assetData->width,
assetData->height,
TEXTURE_FORMAT_PALETTE,
(texturedata_t){
.palette = {
.palette = assetData->paletteIndex,
.data = assetData->palette
}
}
);
errorOk();
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#define ASSET_PALETTE_IMAGE_WIDTH_MAX 128
#define ASSET_PALETTE_IMAGE_HEIGHT_MAX 128
#define ASSET_PALETTE_IMAGE_SIZE_MAX ( \
ASSET_PALETTE_IMAGE_WIDTH_MAX * ASSET_PALETTE_IMAGE_HEIGHT_MAX \
)
#pragma pack(push, 1)
typedef struct {
uint32_t width;
uint32_t height;
uint8_t paletteIndex;
uint8_t palette[ASSET_PALETTE_IMAGE_SIZE_MAX];
} assetpaletteimage_t;
#pragma pack(pop)
/**
* Loads a palette image asset from the given data pointer into the output
* texture.
*
* @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.
*/
errorret_t assetPaletteImageLoad(void *data, void *output);