Asset manager refactor begin.

This commit is contained in:
2025-09-01 21:00:50 -05:00
parent 3e61d6f84d
commit 14c41d33a7
17 changed files with 206 additions and 20 deletions

View File

@@ -1,19 +1,10 @@
# 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
asset.c
assetpalette.c
assettileset.c
assetpaletteimage.c
)
# Compile definitions
target_compile_definitions(${DUSK_TARGET_NAME}
PRIVATE
ASSET_TYPE=wad
assetmanager.c
)

View File

@@ -1,156 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset.h"
#include "util/memory.h"
#include "console/console.h"
#include "util/string.h"
#include "assert/assert.h"
#define ASSET_ASSET_FILE "dusk.dsk"
asset_t ASSET;
errorret_t assetInit(void) {
memoryZero(&ASSET, sizeof(asset_t));
// Open zip file
char_t searchPath[FILENAME_MAX];
consolevar_t *var = consoleVarGet("sys_path");
const char_t *sysPath = var ? var->value : ".";
for(int32_t i = 0; i < ASSET_SEARCH_PATHS_COUNT; i++) {
sprintf(
searchPath,
ASSET_SEARCH_PATHS[i],
sysPath,
ASSET_ASSET_FILE
);
// Try open
ASSET.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
if(ASSET.zip == NULL) continue;
consolePrint("Opened asset file: %s", searchPath);
break;
}
// Did we open the asset?
if(ASSET.zip == NULL) errorThrow("Failed to open asset file.");
errorOk();
}
void assetLoad(
const char_t *filename,
void (*callback)(void* data),
void *data
) {
assertNotNull(filename, "Filename cannot be NULL.");
assertTrue(strlen(filename) < ASSET_FILENAME_MAX, "Filename too long.");
assertTrue(strlen(filename) > 0, "Filename cannot be empty.");
assertTrue(
ASSET.state != ASSET_STATE_LOADING,
"Asset system is already loading an asset."
);
// Determine the asset map type we are expecting based on the extension.
const assetmap_t *expected = &ASSET_MAP[0];
do {
if(stringEndsWith(filename, expected->extension)) break;
expected++;
} while(expected->extension);
assertNotNull(expected->extension, "Unknown asset type.");
// Pass off to the thread to begin loading.
ASSET.callback = callback;
ASSET.callbackData = data;
ASSET.errorState = ERROR_STATE_INIT;
ASSET.state = ASSET_STATE_LOADING;
stringCopy(ASSET.filename, filename, ASSET_FILENAME_MAX);
memoryZero(&ASSET.data, sizeof(ASSET.data));
// For the sake of testing I'm going to do blocking load, fun stuff.
zip_file_t *file = zip_fopen(ASSET.zip, filename, 0);
if(file == NULL) {
ASSET.state = ASSET_STATE_ERROR;
ASSET.error = errorCreate(
&ASSET.errorState,
"Failed to open asset: %s",
filename
);
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
return;
}
printf("Loading asset: %s\n", filename);
// Determine length of the file (uncompressed)
struct zip_stat st;
if(zip_stat(ASSET.zip, filename, 0, &st) != 0) {
zip_fclose(file);
ASSET.state = ASSET_STATE_ERROR;
ASSET.error = errorCreate(
&ASSET.errorState,
"Failed to stat asset: %s",
filename
);
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
return;
}
if(st.size > sizeof(ASSET.data.palette)) {
zip_fclose(file);
ASSET.state = ASSET_STATE_ERROR;
ASSET.error = errorCreate(
&ASSET.errorState,
"Asset size mismatch: %s (got %d, expected %d)",
filename,
(int)st.size,
(int)sizeof(ASSET.data.palette)
);
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
return;
}
// Read entire file into the asset data.
zip_fread(file, &ASSET.data, st.size);
zip_fclose(file);
ASSET.state = ASSET_STATE_LOADED;
if(memoryCompare(
ASSET.data.header, expected->header, ASSET_HEADER_LENGTH
) != 0) {
ASSET.state = ASSET_STATE_ERROR;
ASSET.error = errorCreate(
&ASSET.errorState,
"Asset header mismatch: %s (got %c%c%c, expected %c%c%c)",
filename,
ASSET.data.header[0],
ASSET.data.header[1],
ASSET.data.header[2],
expected->header[0],
expected->header[1],
expected->header[2]
);
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
return;
}
// Parse the asset.
assertNotNull(expected->parser, "Asset parser cannot be NULL.");
expected->parser();
printf("Loaded asset: %s\n", filename);
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
}
void assetDispose(void) {
if(ASSET.zip != NULL) {
zip_close(ASSET.zip);
ASSET.zip = NULL;
}
}

View File

@@ -1,118 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#include "assetpalette.h"
#include "assettileset.h"
#include "assetpalleteimage.h"
#include "error/error.h"
#include <zip.h>
#include "display/texture/texture.h"
#define ASSET_COUNT_MAX 128
#define ASSET_FILENAME_MAX 128
#define ASSET_HEADER_LENGTH 3
#if ASSET_TYPE == wad
#else
#error "Unsupported ASSET_TYPE"
#endif
#pragma pack(push, 1)
typedef struct {
char_t header[ASSET_HEADER_LENGTH];
union {
assetpalette_t palette;
assettileset_t tileset;
assetpaletteimage_t paletteImage;
};
} assetdata_t;
#pragma pack(pop)
typedef struct {
union {
texture_t palette;
assettileset_t *tileset;
texture_t paletteImage;
};
} assetloaded_t;
typedef enum {
ASSET_STATE_NONE,
ASSET_STATE_LOADING,
ASSET_STATE_LOADED,
ASSET_STATE_ERROR
} assetstate_t;
typedef struct {
int32_t nothing;
zip_t *zip;
// thread_t thread;
errorstate_t errorState;
errorret_t error;
assetstate_t state;
char_t filename[ASSET_FILENAME_MAX];
assetdata_t data;
assetloaded_t loaded;
void (*callback)(void* data);
void *callbackData;
} asset_t;
typedef struct {
const char_t *header;
const char_t *extension;
void (*parser)();
} assetmap_t;
static const char_t ASSET_SEARCH_PATHS[][FILENAME_MAX] = {
"%s/%s",
"./%s",
"../%s",
"../../%s",
"data/%s",
"../data/%s",
};
static const assetmap_t ASSET_MAP[] = {
{ "DPF", ".dpf", assetParsePalette },
{ "DPT", ".dpt", assetParseTileset },
{ "DPI", ".dpi", assetParsePaletteImage },
{ NULL, NULL, NULL }
};
#define ASSET_SEARCH_PATHS_COUNT (\
sizeof(ASSET_SEARCH_PATHS) / FILENAME_MAX\
)
extern asset_t ASSET;
/**
* Initializes the asset system.
*/
errorret_t assetInit(void);
/**
* Loads an asset by filename, blocking.
*
* @param filename The filename of the asset to get.
* @param callback The callback to call when the asset is loaded.
* @param data The data for the callback function.
* @return The asset.
*/
void assetLoad(
const char_t *filename,
void (*callback)(void* data),
void *data
);
/**
* Disposes/cleans up the asset system.
*/
void assetDispose(void);

51
src/asset/assetmanager.c Normal file
View File

@@ -0,0 +1,51 @@
/**
* 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 "console/console.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));
// Open zip file
char_t searchPath[FILENAME_MAX];
consolevar_t *var = consoleVarGet("sys_path");
const char_t *sysPath = var ? var->value : ".";
for(int32_t i = 0; i < ASSET_MANAGER_SEARCH_PATHS_COUNT; i++) {
sprintf(
searchPath,
ASSET_MANAGER_SEARCH_PATHS[i],
sysPath,
ASSET_ASSET_FILE
);
// Try open
ASSET_MANAGER.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
if(ASSET_MANAGER.zip == NULL) continue;
consolePrint("Opened asset file: %s", searchPath);
break;
}
// Did we open the asset?
if(ASSET_MANAGER.zip == NULL) errorThrow("Failed to open asset file.");
errorOk();
}
void assetManagerDispose(void) {
if(ASSET_MANAGER.zip != NULL) {
zip_close(ASSET_MANAGER.zip);
ASSET_MANAGER.zip = NULL;
}
}

46
src/asset/assetmanager.h Normal file
View File

@@ -0,0 +1,46 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "error/error.h"
#include <zip.h>
#include "display/texture/texture.h"
#if ASSET_TYPE == wad
#else
#error "Unsupported ASSET_TYPE"
#endif
static const char_t ASSET_MANAGER_SEARCH_PATHS[][FILENAME_MAX] = {
"%s/%s",
"./%s",
"../%s",
"../../%s",
"data/%s",
"../data/%s",
};
#define ASSET_MANAGER_SEARCH_PATHS_COUNT (\
sizeof(ASSET_MANAGER_SEARCH_PATHS) / FILENAME_MAX\
)
typedef struct {
int32_t nothing;
zip_t *zip;
} assetmanager_t;
extern assetmanager_t ASSET_MANAGER;
/**
* Initializes the asset system.
*/
errorret_t assetManagerInit(void);
/**
* Disposes/cleans up the asset system.
*/
void assetManagerDispose(void);

View File

@@ -1,18 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset.h"
void assetParsePalette() {
textureInit(
&ASSET.loaded.palette,
ASSET.data.palette.colorCount,
1,
TEXTURE_FORMAT_RGBA,
ASSET.data.palette.colors
);
}

View File

@@ -1,22 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#include "display/color.h"
#define ASSET_PALETTE_COLOR_COUNT_MAX 256
typedef struct {
int32_t colorCount;
color4b_t colors[ASSET_PALETTE_COLOR_COUNT_MAX];
} assetpalette_t;
/**
* Parse the palette from the loaded raw data.
*/
void assetParsePalette(void);

View File

@@ -1,12 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset.h"
void assetParsePaletteImage(void) {
printf("nothin doin\n");
}

View File

@@ -1,23 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
#define ASSET_PALETTE_IMAGE_PIXELS_MAX (256*256)
typedef struct {
int32_t width;
int32_t height;
uint8_t paletteIndex;
uint8_t paletteIndexes[ASSET_PALETTE_IMAGE_PIXELS_MAX];
} assetpaletteimage_t;
/**
* Parse the palette image from the loaded raw data.
*/
void assetParsePaletteImage(void);

View File

@@ -1,12 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "asset.h"
void assetParseTileset() {
ASSET.loaded.tileset = &ASSET.data.tileset;
}

View File

@@ -1,24 +0,0 @@
/**
* Copyright (c) 2025 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "dusk.h"
typedef struct assetimage_s assetimage_t;
typedef struct {
int32_t tileWidth;
int32_t tileHeight;
int32_t tileCount;
int32_t columns;
char_t tilesetName[256];
} assettileset_t;
/**
* Parse the tileset from the loaded raw data.
*/
void assetParseTileset(void);

View File

@@ -10,7 +10,7 @@
#include "time/time.h"
#include "console/console.h"
#include "display/display.h"
#include "asset/asset.h"
#include "asset/assetmanager.h"
#include "rpg/rpg.h"
engine_t ENGINE;
@@ -22,7 +22,7 @@ errorret_t engineInit(void) {
// Init systems. Order is important.
timeInit();
consoleInit();
errorChain(assetInit());
errorChain(assetManagerInit());
errorChain(displayInit());
rpgInit();
@@ -39,7 +39,7 @@ errorret_t engineUpdate(void) {
errorret_t engineDispose(void) {
errorChain(displayDispose());
assetDispose();
assetManagerDispose();
consoleDispose();
errorOk();