Asset manager refactor begin.
This commit is contained in:
19
archive/asset/CMakeLists.txt
Normal file
19
archive/asset/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
# 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
|
||||
)
|
156
archive/asset/asset.c
Normal file
156
archive/asset/asset.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
118
archive/asset/asset.h
Normal file
118
archive/asset/asset.h
Normal file
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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);
|
18
archive/asset/assetpalette.c
Normal file
18
archive/asset/assetpalette.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* 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
|
||||
);
|
||||
}
|
22
archive/asset/assetpalette.h
Normal file
22
archive/asset/assetpalette.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* 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);
|
12
archive/asset/assetpaletteimage.c
Normal file
12
archive/asset/assetpaletteimage.c
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* 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");
|
||||
}
|
23
archive/asset/assetpalleteimage.h
Normal file
23
archive/asset/assetpalleteimage.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* 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);
|
12
archive/asset/assettileset.c
Normal file
12
archive/asset/assettileset.c
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
24
archive/asset/assettileset.h
Normal file
24
archive/asset/assettileset.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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);
|
Reference in New Issue
Block a user