First refactor of new asset system
This commit is contained in:
@@ -139,7 +139,7 @@ errorret_t assetUpdate(void) {
|
|||||||
case ASSET_ENTRY_STATE_PENDING_SYNC:
|
case ASSET_ENTRY_STATE_PENDING_SYNC:
|
||||||
// Begin sync loading
|
// Begin sync loading
|
||||||
loading->entry->state = ASSET_ENTRY_STATE_LOADING_SYNC;
|
loading->entry->state = ASSET_ENTRY_STATE_LOADING_SYNC;
|
||||||
errorret_t ret = ASSET_LOADING_CALLBACKS[loading->type].loadSync(loading);
|
errorret_t ret = ASSET_LOADER_CALLBACKS[loading->type].loadSync(loading);
|
||||||
if(ret.code != ERROR_OK) {
|
if(ret.code != ERROR_OK) {
|
||||||
loading->entry->state = ASSET_ENTRY_STATE_ERROR;
|
loading->entry->state = ASSET_ENTRY_STATE_ERROR;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -158,6 +158,7 @@ errorret_t assetUpdate(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t assetDispose(void) {
|
errorret_t assetDispose(void) {
|
||||||
|
// Cleanup zip file.
|
||||||
if(ASSET.zip != NULL) {
|
if(ASSET.zip != NULL) {
|
||||||
if(zip_close(ASSET.zip) != 0) {
|
if(zip_close(ASSET.zip) != 0) {
|
||||||
errorThrow("Failed to close asset zip archive.");
|
errorThrow("Failed to close asset zip archive.");
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
assetentry.c
|
assetentry.c
|
||||||
assetloading.c
|
assetloader.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,30 +10,6 @@
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
|
||||||
assetentrycallbacks_t ASSET_ENTRY_CALLBACKS[ASSET_LOADER_TYPE_COUNT] = {
|
|
||||||
[ASSET_LOADER_TYPE_NULL] = { 0 },
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_MESH] = {
|
|
||||||
.dispose = &assetMeshDisposeNEW
|
|
||||||
},
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_TEXTURE] = {
|
|
||||||
.dispose = &assetTextureDisposeNEW
|
|
||||||
},
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_TILESET] = {
|
|
||||||
.dispose = &assetTilesetDisposeNEW
|
|
||||||
},
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_LOCALE] = {
|
|
||||||
.dispose = &assetLocaleDisposeNEW
|
|
||||||
},
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_JSON] = {
|
|
||||||
.dispose = &assetJsonDisposeNEW
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
void assetEntryInit(
|
void assetEntryInit(
|
||||||
assetentry_t *entry,
|
assetentry_t *entry,
|
||||||
const char_t *name,
|
const char_t *name,
|
||||||
@@ -91,7 +67,7 @@ errorret_t assetEntryDispose(assetentry_t *entry) {
|
|||||||
assertTrue(entry->type != ASSET_LOADER_TYPE_NULL, "Invalid loader type.");
|
assertTrue(entry->type != ASSET_LOADER_TYPE_NULL, "Invalid loader type.");
|
||||||
assertTrue(entry->type < ASSET_LOADER_TYPE_COUNT, "Invalid loader type.");
|
assertTrue(entry->type < ASSET_LOADER_TYPE_COUNT, "Invalid loader type.");
|
||||||
|
|
||||||
errorChain(ASSET_ENTRY_CALLBACKS[entry->type].dispose(entry));
|
errorChain(ASSET_LOADER_CALLBACKS[entry->type].dispose(entry));
|
||||||
memoryZero(entry, sizeof(assetentry_t));
|
memoryZero(entry, sizeof(assetentry_t));
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -34,14 +34,6 @@ typedef struct assetentry_s {
|
|||||||
assetloaderinput_t *input;
|
assetloaderinput_t *input;
|
||||||
} assetentry_t;
|
} assetentry_t;
|
||||||
|
|
||||||
typedef errorret_t (*assetentrydisposecallback_t)(assetentry_t *entry);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
assetentrydisposecallback_t dispose;
|
|
||||||
} assetentrycallbacks_t;
|
|
||||||
|
|
||||||
extern assetentrycallbacks_t ASSET_ENTRY_CALLBACKS[ASSET_LOADER_TYPE_COUNT];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an asset entry with the given name and type. This does not load
|
* Initializes an asset entry with the given name and type. This does not load
|
||||||
* the asset.
|
* the asset.
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assetloader.h"
|
||||||
|
|
||||||
|
assetloadercallbacks_t ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_COUNT] = {
|
||||||
|
[ASSET_LOADER_TYPE_NULL] = { 0 },
|
||||||
|
|
||||||
|
[ASSET_LOADER_TYPE_MESH] = {
|
||||||
|
.loadSync = assetMeshLoaderNEW,
|
||||||
|
.dispose = assetMeshDisposeNEW
|
||||||
|
},
|
||||||
|
|
||||||
|
[ASSET_LOADER_TYPE_TEXTURE] = {
|
||||||
|
.loadSync = assetTextureLoaderSync,
|
||||||
|
.dispose = assetTextureDispose
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
[ASSET_LOADER_TYPE_TILESET] = {
|
||||||
|
.loadSync = assetTilesetLoaderNEW,
|
||||||
|
.dispose = assetTilesetDisposeNEW
|
||||||
|
},
|
||||||
|
|
||||||
|
[ASSET_LOADER_TYPE_LOCALE] = {
|
||||||
|
.loadSync = assetLocaleLoaderNEW,
|
||||||
|
.dispose = assetLocaleDisposeNEW
|
||||||
|
},
|
||||||
|
|
||||||
|
[ASSET_LOADER_TYPE_JSON] = {
|
||||||
|
.loadSync = assetJsonLoaderNEW,
|
||||||
|
.dispose = assetJsonDisposeNEW
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -46,4 +46,17 @@ typedef union {
|
|||||||
assettilesetoutput_t tileset;
|
assettilesetoutput_t tileset;
|
||||||
assetlocaleoutput_t locale;
|
assetlocaleoutput_t locale;
|
||||||
assetjsonoutput_t json;
|
assetjsonoutput_t json;
|
||||||
} assetloaderoutput_t;
|
} assetloaderoutput_t;
|
||||||
|
|
||||||
|
typedef struct assetloading_s assetloading_t;
|
||||||
|
typedef struct assetentry_s assetentry_t;
|
||||||
|
|
||||||
|
typedef errorret_t (assetloadersynccallback_t)(assetloading_t *loading);
|
||||||
|
typedef errorret_t (assetloaderdisposecallback_t)(assetentry_t *entry);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
assetloadersynccallback_t *loadSync;
|
||||||
|
assetloaderdisposecallback_t *dispose;
|
||||||
|
} assetloadercallbacks_t;
|
||||||
|
|
||||||
|
extern assetloadercallbacks_t ASSET_LOADER_CALLBACKS[ASSET_LOADER_TYPE_COUNT];
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "assetloading.h"
|
|
||||||
#include "asset/loader/display/assetmeshloader.h"
|
|
||||||
|
|
||||||
assetloadingcallbacks_t ASSET_LOADING_CALLBACKS[ASSET_LOADER_TYPE_COUNT] = {
|
|
||||||
[ASSET_LOADER_TYPE_NULL] = { 0 },
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_MESH] = {
|
|
||||||
.loadSync = assetMeshLoaderNEW,
|
|
||||||
},
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_TEXTURE] = {
|
|
||||||
.loadSync = assetTextureLoaderNEW
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_TILESET] = {
|
|
||||||
.loadSync = assetTilesetLoaderNEW
|
|
||||||
},
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_LOCALE] = {
|
|
||||||
.loadSync = assetLocaleLoaderNEW
|
|
||||||
},
|
|
||||||
|
|
||||||
[ASSET_LOADER_TYPE_JSON] = {
|
|
||||||
.loadSync = assetJsonLoaderNEW
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -25,5 +25,3 @@ typedef errorret_t (assetloadingcallback_t)(assetloading_t *loading);
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
assetloadingcallback_t *loadSync;
|
assetloadingcallback_t *loadSync;
|
||||||
} assetloadingcallbacks_t;
|
} assetloadingcallbacks_t;
|
||||||
|
|
||||||
extern assetloadingcallbacks_t ASSET_LOADING_CALLBACKS[ASSET_LOADER_TYPE_COUNT];
|
|
||||||
@@ -11,36 +11,9 @@
|
|||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
#include "util/endian.h"
|
#include "util/endian.h"
|
||||||
|
|
||||||
|
|
||||||
#include "asset/loader/assetloading.h"
|
#include "asset/loader/assetloading.h"
|
||||||
#include "asset/loader/assetentry.h"
|
#include "asset/loader/assetentry.h"
|
||||||
|
|
||||||
errorret_t assetTextureLoaderNEW(assetloading_t *loading) {
|
|
||||||
assertNotNull(loading, "Loading cannot be NULL");
|
|
||||||
|
|
||||||
assettextureloaderparams_t params;
|
|
||||||
params.format = loading->entry->input->texture;
|
|
||||||
|
|
||||||
assetfile_t *file = &loading->loading.texture.file;
|
|
||||||
errorChain(assetFileInit(
|
|
||||||
file,
|
|
||||||
loading->entry->name,
|
|
||||||
¶ms,
|
|
||||||
&loading->entry->data.texture
|
|
||||||
));
|
|
||||||
errorChain(assetTextureLoader(file));
|
|
||||||
assetFileDispose(file);
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t assetTextureDisposeNEW(assetentry_t *entry) {
|
|
||||||
assertNotNull(entry, "Asset entry cannot be NULL");
|
|
||||||
return textureDispose(&entry->data.texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
stbi_io_callbacks ASSET_TEXTURE_STB_CALLBACKS = {
|
stbi_io_callbacks ASSET_TEXTURE_STB_CALLBACKS = {
|
||||||
.read = assetTextureReader,
|
.read = assetTextureReader,
|
||||||
.skip = assetTextureSkipper,
|
.skip = assetTextureSkipper,
|
||||||
@@ -79,16 +52,23 @@ int assetTextureEOF(void *user) {
|
|||||||
return file->position >= file->size;
|
return file->position >= file->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t assetTextureLoader(assetfile_t *file) {
|
errorret_t assetTextureLoaderSync(assetloading_t *loading) {
|
||||||
assertNotNull(file, "Asset file cannot be NULL.");
|
assertNotNull(loading, "Loading cannot be NULL");
|
||||||
assertNotNull(file->params, "Asset file parameters cannot be NULL.");
|
|
||||||
assertNotNull(file->output, "Asset file output cannot be NULL.");
|
|
||||||
|
|
||||||
assettextureloaderparams_t *p = (assettextureloaderparams_t*)file->params;
|
|
||||||
assertNotNull(p, "Asset texture loader parameters cannot be NULL.");
|
// Init the file
|
||||||
|
assetfile_t *file = &loading->loading.texture.file;
|
||||||
|
errorChain(assetFileInit(
|
||||||
|
file,
|
||||||
|
loading->entry->name,
|
||||||
|
NULL,
|
||||||
|
&loading->entry->data.texture
|
||||||
|
));
|
||||||
|
errorChain(assetFileOpen(file));
|
||||||
|
|
||||||
|
// Determine channels
|
||||||
int channelsDesired;
|
int channelsDesired;
|
||||||
switch(p->format) {
|
switch(loading->entry->input->texture) {
|
||||||
case TEXTURE_FORMAT_RGBA:
|
case TEXTURE_FORMAT_RGBA:
|
||||||
channelsDesired = 4;
|
channelsDesired = 4;
|
||||||
break;
|
break;
|
||||||
@@ -97,9 +77,9 @@ errorret_t assetTextureLoader(assetfile_t *file) {
|
|||||||
errorThrow("Bad texture format.");
|
errorThrow("Bad texture format.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load image pixels.
|
||||||
int width, height, channels;
|
int width, height, channels;
|
||||||
errorChain(assetFileOpen(file));
|
loading->loading.texture.data = stbi_load_from_callbacks(
|
||||||
uint8_t *data = stbi_load_from_callbacks(
|
|
||||||
&ASSET_TEXTURE_STB_CALLBACKS,
|
&ASSET_TEXTURE_STB_CALLBACKS,
|
||||||
file,
|
file,
|
||||||
&width,
|
&width,
|
||||||
@@ -107,27 +87,41 @@ errorret_t assetTextureLoader(assetfile_t *file) {
|
|||||||
&channels,
|
&channels,
|
||||||
channelsDesired
|
channelsDesired
|
||||||
);
|
);
|
||||||
errorChain(assetFileClose(file));
|
|
||||||
|
|
||||||
if(data == NULL) {
|
// Close out the file.
|
||||||
|
errorChain(assetFileClose(file));
|
||||||
|
errorChain(assetFileDispose(file));
|
||||||
|
|
||||||
|
// Ensure we loaded correctly.
|
||||||
|
if(loading->loading.texture.data == NULL) {
|
||||||
const char_t *errorStr = stbi_failure_reason();
|
const char_t *errorStr = stbi_failure_reason();
|
||||||
errorThrow("Failed to load texture from file %s.", errorStr);
|
errorThrow("Failed to load texture from file %s.", errorStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixes a specific bug probably with Dolphin but for now just assuming endian
|
// Fixes a specific bug probably with Dolphin but for now just assuming endian
|
||||||
if(!isHostLittleEndian()) {
|
if(!isHostLittleEndian()) {
|
||||||
stbi__vertical_flip(data, width, height, channelsDesired);
|
stbi__vertical_flip(
|
||||||
|
loading->loading.texture.data,
|
||||||
|
width, height, channelsDesired
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the texture.
|
||||||
errorChain(textureInit(
|
errorChain(textureInit(
|
||||||
(texture_t*)file->output,
|
(texture_t*)&loading->entry->data.texture,
|
||||||
(int32_t)width, (int32_t)height,
|
(int32_t)width, (int32_t)height,
|
||||||
p->format,
|
loading->entry->input->texture,
|
||||||
(texturedata_t){
|
(texturedata_t){
|
||||||
.rgbaColors = (color_t*)data
|
.rgbaColors = (color_t*)loading->loading.texture.data
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|
||||||
stbi_image_free(data);
|
// Free the pixels.
|
||||||
|
stbi_image_free(loading->loading.texture.data);
|
||||||
errorOk();
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t assetTextureDispose(assetentry_t *entry) {
|
||||||
|
assertNotNull(entry, "Asset entry cannot be NULL");
|
||||||
|
return textureDispose(&entry->data.texture);
|
||||||
}
|
}
|
||||||
@@ -9,25 +9,17 @@
|
|||||||
#include "asset/assetfile.h"
|
#include "asset/assetfile.h"
|
||||||
#include "display/texture/texture.h"
|
#include "display/texture/texture.h"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
textureformat_t format;
|
|
||||||
} assettextureloaderparams_t;
|
|
||||||
|
|
||||||
// NEW STUFF
|
|
||||||
typedef struct assetloading_s assetloading_t;
|
typedef struct assetloading_s assetloading_t;
|
||||||
typedef struct assetentry_s assetentry_t;
|
typedef struct assetentry_s assetentry_t;
|
||||||
|
|
||||||
typedef textureformat_t assettextureloaderinput_t;
|
typedef textureformat_t assettextureloaderinput_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
assetfile_t file;
|
assetfile_t file;
|
||||||
|
uint8_t *data;
|
||||||
} assettextureloaderloading_t;
|
} assettextureloaderloading_t;
|
||||||
|
|
||||||
typedef texture_t assettextureoutput_t;
|
typedef texture_t assettextureoutput_t;
|
||||||
|
|
||||||
errorret_t assetTextureLoaderNEW(assetloading_t *loading);
|
|
||||||
errorret_t assetTextureDisposeNEW(assetentry_t *entry);
|
|
||||||
|
|
||||||
// END NEW STUFF
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* STB image read callback for asset files.
|
* STB image read callback for asset files.
|
||||||
*
|
*
|
||||||
@@ -38,14 +30,34 @@ errorret_t assetTextureDisposeNEW(assetentry_t *entry);
|
|||||||
*/
|
*/
|
||||||
int assetTextureReader(void *user, char *data, int size);
|
int assetTextureReader(void *user, char *data, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STB image skip callback for asset files.
|
||||||
|
*
|
||||||
|
* @param user User data passed to the callback, should be an assetfile_t*.
|
||||||
|
* @param n Number of bytes to skip in the file.
|
||||||
|
*/
|
||||||
void assetTextureSkipper(void *user, int n);
|
void assetTextureSkipper(void *user, int n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* STB image EOF callback for asset files.
|
||||||
|
*
|
||||||
|
* @param user User data passed to the callback, should be an assetfile_t*.
|
||||||
|
* @return Non-zero if end of file has been reached, zero otherwise.
|
||||||
|
*/
|
||||||
int assetTextureEOF(void *user);
|
int assetTextureEOF(void *user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for texture assets.
|
* Synchronous loader for texture assets.
|
||||||
*
|
*
|
||||||
* @param file Asset file to load the texture from.
|
* @param loading Loading information for the asset being loaded.
|
||||||
* @return Any error that occurs during loading.
|
* @return Error code indicating success or failure of the load operation.
|
||||||
*/
|
*/
|
||||||
errorret_t assetTextureLoader(assetfile_t *file);
|
errorret_t assetTextureLoaderSync(assetloading_t *loading);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposer for texture assets.
|
||||||
|
*
|
||||||
|
* @param entry Asset entry containing the texture to dispose.
|
||||||
|
* @return Error code indicating success or failure of the dispose operation.
|
||||||
|
*/
|
||||||
|
errorret_t assetTextureDispose(assetentry_t *entry);
|
||||||
Reference in New Issue
Block a user