Started asset refact
This commit is contained in:
14
archive/asset/CMakeLists.txt
Normal file
14
archive/asset/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# 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
|
||||||
|
assetmanager.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
|
add_subdirectory(type)
|
||||||
139
archive/asset/asset.c
Normal file
139
archive/asset/asset.c
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "asset.h"
|
||||||
|
#include "assetmanager.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = {
|
||||||
|
[ASSET_TYPE_PALETTE_IMAGE] = {
|
||||||
|
"DPI", assetPaletteImageLoad, assetPaletteImageDispose
|
||||||
|
},
|
||||||
|
[ASSET_TYPE_ALPHA_IMAGE] = {
|
||||||
|
"DAI", assetAlphaImageLoad, assetAlphaImageDispose
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
||||||
|
assertNotNull(asset, "Asset cannot be NULL.");
|
||||||
|
assertNotNull(filename, "Filename cannot be NULL.");
|
||||||
|
assertTrue(strlen(filename) < FILENAME_MAX, "Filename too long.");
|
||||||
|
assertTrue(strlen(filename) > 0, "Filename cannot be empty.");
|
||||||
|
|
||||||
|
memoryZero(asset, sizeof(asset_t));
|
||||||
|
memoryCopy(asset->filename, filename, strlen(filename) + 1);
|
||||||
|
|
||||||
|
// Initialze the reference list.
|
||||||
|
refListInit(
|
||||||
|
&asset->refList,
|
||||||
|
asset->refListArray,
|
||||||
|
ASSET_REFERENCE_COUNT_MAX
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test the file can be opened. In future I may make the handle stay open for
|
||||||
|
// a while to see if it increases performance and stops disk thrashing.
|
||||||
|
asset->file = zip_fopen(ASSET_MANAGER.zip, filename, 0);
|
||||||
|
if(asset->file == NULL) errorThrow("Failed to open asset file: %s", filename);
|
||||||
|
zip_fclose(asset->file);
|
||||||
|
asset->file = NULL;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_t assetLock(asset_t *asset) {
|
||||||
|
assertNotNull(asset, "Asset cannot be NULL.");
|
||||||
|
|
||||||
|
return refListLock(&asset->refList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetUnlock(asset_t *asset, const ref_t ref) {
|
||||||
|
assertNotNull(asset, "Asset cannot be NULL.");
|
||||||
|
|
||||||
|
// Just unlock the reference in the reference list.
|
||||||
|
refListUnlock(&asset->refList, ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t assetLoad(asset_t *asset) {
|
||||||
|
assertNotNull(asset, "Asset cannot be NULL.");
|
||||||
|
assertTrue(
|
||||||
|
asset->state == ASSET_STATE_NOT_LOADED,
|
||||||
|
"Asset is already loaded or loading."
|
||||||
|
);
|
||||||
|
|
||||||
|
// Mark as loading.
|
||||||
|
asset->state = ASSET_STATE_LOADING;
|
||||||
|
|
||||||
|
// Open the file.
|
||||||
|
if(asset->file == NULL) {
|
||||||
|
asset->file = zip_fopen(ASSET_MANAGER.zip, asset->filename, 0);
|
||||||
|
if(asset->file == NULL) {
|
||||||
|
asset->state = ASSET_STATE_ERROR;
|
||||||
|
errorThrow("Failed to open asset file: %s", asset->filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read header.
|
||||||
|
char_t header[ASSET_HEADER_SIZE + 1];
|
||||||
|
memoryZero(header, ASSET_HEADER_SIZE + 1);
|
||||||
|
zip_int64_t bytesRead = zip_fread(asset->file, header, ASSET_HEADER_SIZE);
|
||||||
|
if(bytesRead != ASSET_HEADER_SIZE) {
|
||||||
|
asset->state = ASSET_STATE_ERROR;
|
||||||
|
zip_fclose(asset->file);
|
||||||
|
asset->file = NULL;
|
||||||
|
errorThrow("Failed to read asset header for: %s", asset->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check header.
|
||||||
|
if(strlen(header) != ASSET_HEADER_SIZE) {
|
||||||
|
asset->state = ASSET_STATE_ERROR;
|
||||||
|
zip_fclose(asset->file);
|
||||||
|
asset->file = NULL;
|
||||||
|
errorThrow("Invalid asset header for: %s", asset->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the asset definition based on the header.
|
||||||
|
assetdef_t *def;
|
||||||
|
for(uint_fast8_t i = 0; i < ASSET_TYPE_COUNT; i++) {
|
||||||
|
if(strcmp(header, ASSET_DEFINITIONS[i].header) == 0) {
|
||||||
|
def = &ASSET_DEFINITIONS[i];
|
||||||
|
asset->type = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertNotNull(def, "Failed to find asset definition for header.");
|
||||||
|
|
||||||
|
// Load the asset
|
||||||
|
errorret_t ret = def->load(asset);
|
||||||
|
if(ret.code != ERROR_OK) {
|
||||||
|
asset->state = ASSET_STATE_ERROR;
|
||||||
|
zip_fclose(asset->file);
|
||||||
|
asset->file = NULL;
|
||||||
|
errorChain(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finished loading.
|
||||||
|
asset->state = ASSET_STATE_LOADED;
|
||||||
|
zip_fclose(asset->file);
|
||||||
|
asset->file = NULL;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t assetDispose(asset_t *asset) {
|
||||||
|
assertNotNull(asset, "Asset cannot be NULL.");
|
||||||
|
|
||||||
|
if(asset->state == ASSET_STATE_LOADED) {
|
||||||
|
// Dispose of the asset based on its type.
|
||||||
|
assetdef_t *def = &ASSET_DEFINITIONS[asset->type];
|
||||||
|
if(def->dispose) errorChain(def->dispose(asset));
|
||||||
|
asset->state = ASSET_STATE_NOT_LOADED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(asset->file) {
|
||||||
|
zip_fclose(asset->file);
|
||||||
|
asset->file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
104
archive/asset/asset.h
Normal file
104
archive/asset/asset.h
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
/**
|
||||||
|
* 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 "util/reflist.h"
|
||||||
|
#include <zip.h>
|
||||||
|
|
||||||
|
#include "asset/type/assetpaletteimage.h"
|
||||||
|
#include "asset/type/assetalphaimage.h"
|
||||||
|
|
||||||
|
#define ASSET_HEADER_SIZE 3
|
||||||
|
#define ASSET_REFERENCE_COUNT_MAX 8
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void (*load)();
|
||||||
|
} assetcallback_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ASSET_STATE_NOT_LOADED,
|
||||||
|
ASSET_STATE_LOADING,
|
||||||
|
ASSET_STATE_LOADED,
|
||||||
|
ASSET_STATE_ERROR,
|
||||||
|
} assetstate_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ASSET_TYPE_UNKNOWN,
|
||||||
|
ASSET_TYPE_PALETTE_IMAGE,
|
||||||
|
ASSET_TYPE_ALPHA_IMAGE,
|
||||||
|
|
||||||
|
ASSET_TYPE_COUNT
|
||||||
|
} assettype_t;
|
||||||
|
|
||||||
|
typedef struct asset_s {
|
||||||
|
char_t filename[FILENAME_MAX];
|
||||||
|
ref_t refListArray[ASSET_REFERENCE_COUNT_MAX];
|
||||||
|
reflist_t refList;
|
||||||
|
assetstate_t state;
|
||||||
|
assettype_t type;
|
||||||
|
zip_file_t *file;
|
||||||
|
|
||||||
|
union {
|
||||||
|
assetpaletteimage_t paletteImage;
|
||||||
|
assetalphaimage_t alphaImage;
|
||||||
|
};
|
||||||
|
} asset_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char_t header[ASSET_HEADER_SIZE + 1];
|
||||||
|
errorret_t (*load)(asset_t *asset);
|
||||||
|
errorret_t (*dispose)(asset_t *asset);
|
||||||
|
} assetdef_t;
|
||||||
|
|
||||||
|
extern assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes an asset structure. This should be called by the asset manager
|
||||||
|
* only.
|
||||||
|
*
|
||||||
|
* @param asset The asset structure to initialize.
|
||||||
|
* @param filename The filename of the asset.
|
||||||
|
* @return An error code.
|
||||||
|
*/
|
||||||
|
errorret_t assetInit(asset_t *asset, const char_t *filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests a lock on the given asset. This will increase the reference count
|
||||||
|
* of the asset, and prevent it from being unloaded until all locks are
|
||||||
|
* released.
|
||||||
|
*
|
||||||
|
* @param asset The asset to lock.
|
||||||
|
* @return A unique reference ID for the lock.
|
||||||
|
*/
|
||||||
|
ref_t assetLock(asset_t *asset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases a lock on the given asset. This will decrease the reference count
|
||||||
|
* of the asset, and allow it to be unloaded if there are no more locks.
|
||||||
|
*
|
||||||
|
* @param asset The asset to unlock.
|
||||||
|
* @param ref The reference ID of the lock to release.
|
||||||
|
*/
|
||||||
|
void assetUnlock(asset_t *asset, const ref_t ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permission has been granted to load the asset data from disk. This should
|
||||||
|
* only be called by the asset manager.
|
||||||
|
*
|
||||||
|
* @param asset The asset to load.
|
||||||
|
* @return An error code.
|
||||||
|
*/
|
||||||
|
errorret_t assetLoad(asset_t *asset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of the asset, freeing any allocated memory and closing any open
|
||||||
|
* file handles. This should only be called by the asset manager.
|
||||||
|
*
|
||||||
|
* @param asset The asset to dispose of.
|
||||||
|
*/
|
||||||
|
errorret_t assetDispose(asset_t *asset);
|
||||||
@@ -34,7 +34,7 @@ add_subdirectory(display)
|
|||||||
add_subdirectory(engine)
|
add_subdirectory(engine)
|
||||||
add_subdirectory(error)
|
add_subdirectory(error)
|
||||||
add_subdirectory(input)
|
add_subdirectory(input)
|
||||||
# add_subdirectory(locale)
|
add_subdirectory(locale)
|
||||||
add_subdirectory(rpg)
|
add_subdirectory(rpg)
|
||||||
add_subdirectory(scene)
|
add_subdirectory(scene)
|
||||||
add_subdirectory(thread)
|
add_subdirectory(thread)
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
# Sources
|
# Sources
|
||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
asset.c
|
# asset.c
|
||||||
assetmanager.c
|
# assetmanager.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Subdirs
|
# Subdirs
|
||||||
add_subdirectory(type)
|
# add_subdirectory(type)
|
||||||
@@ -6,134 +6,46 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "asset.h"
|
#include "asset.h"
|
||||||
#include "assetmanager.h"
|
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
|
|
||||||
assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT] = {
|
errorret_t assetInit(void) {
|
||||||
[ASSET_TYPE_PALETTE_IMAGE] = {
|
memoryZero(&ASSET_MANAGER, sizeof(assetmanager_t));
|
||||||
"DPI", assetPaletteImageLoad, assetPaletteImageDispose
|
|
||||||
},
|
|
||||||
[ASSET_TYPE_ALPHA_IMAGE] = {
|
|
||||||
"DAI", assetAlphaImageLoad, assetAlphaImageDispose
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
errorret_t assetInit(asset_t *asset, const char_t *filename) {
|
// Default system path, intended to be overridden by the paltform
|
||||||
assertNotNull(asset, "Asset cannot be NULL.");
|
stringCopy(ASSET_MANAGER.systemPath, ".", FILENAME_MAX);
|
||||||
assertNotNull(filename, "Filename cannot be NULL.");
|
|
||||||
assertTrue(strlen(filename) < FILENAME_MAX, "Filename too long.");
|
|
||||||
assertTrue(strlen(filename) > 0, "Filename cannot be empty.");
|
|
||||||
|
|
||||||
memoryZero(asset, sizeof(asset_t));
|
// Open zip file
|
||||||
memoryCopy(asset->filename, filename, strlen(filename) + 1);
|
char_t searchPath[FILENAME_MAX];
|
||||||
|
char_t **path = ASSET_SEARCH_PATHS;
|
||||||
|
do {
|
||||||
|
sprintf(
|
||||||
|
searchPath,
|
||||||
|
*path,
|
||||||
|
ASSET_MANAGER.systemPath,
|
||||||
|
ASSET_ASSET_FILE
|
||||||
|
);
|
||||||
|
|
||||||
// Initialze the reference list.
|
// Try open
|
||||||
refListInit(
|
ASSET.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
|
||||||
&asset->refList,
|
if(ASSET.zip == NULL) continue;
|
||||||
asset->refListArray,
|
break;// Found!
|
||||||
ASSET_REFERENCE_COUNT_MAX
|
} while(*(++path) != NULL);
|
||||||
);
|
|
||||||
|
// Did we open the asset?
|
||||||
|
if(ASSET.zip == NULL) errorThrow("Failed to open asset file.");
|
||||||
|
|
||||||
// Test the file can be opened. In future I may make the handle stay open for
|
|
||||||
// a while to see if it increases performance and stops disk thrashing.
|
|
||||||
asset->file = zip_fopen(ASSET_MANAGER.zip, filename, 0);
|
|
||||||
if(asset->file == NULL) errorThrow("Failed to open asset file: %s", filename);
|
|
||||||
zip_fclose(asset->file);
|
|
||||||
asset->file = NULL;
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
ref_t assetLock(asset_t *asset) {
|
erroret_t assetLoad(const char_t *filename, void *output) {
|
||||||
assertNotNull(asset, "Asset cannot be NULL.");
|
|
||||||
|
|
||||||
return refListLock(&asset->refList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void assetUnlock(asset_t *asset, const ref_t ref) {
|
|
||||||
assertNotNull(asset, "Asset cannot be NULL.");
|
|
||||||
|
|
||||||
// Just unlock the reference in the reference list.
|
|
||||||
refListUnlock(&asset->refList, ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t assetLoad(asset_t *asset) {
|
|
||||||
assertNotNull(asset, "Asset cannot be NULL.");
|
|
||||||
assertTrue(
|
|
||||||
asset->state == ASSET_STATE_NOT_LOADED,
|
|
||||||
"Asset is already loaded or loading."
|
|
||||||
);
|
|
||||||
|
|
||||||
// Mark as loading.
|
|
||||||
asset->state = ASSET_STATE_LOADING;
|
|
||||||
|
|
||||||
// Open the file.
|
|
||||||
if(asset->file == NULL) {
|
|
||||||
asset->file = zip_fopen(ASSET_MANAGER.zip, asset->filename, 0);
|
|
||||||
if(asset->file == NULL) {
|
|
||||||
asset->state = ASSET_STATE_ERROR;
|
|
||||||
errorThrow("Failed to open asset file: %s", asset->filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read header.
|
|
||||||
char_t header[ASSET_HEADER_SIZE + 1];
|
|
||||||
memoryZero(header, ASSET_HEADER_SIZE + 1);
|
|
||||||
zip_int64_t bytesRead = zip_fread(asset->file, header, ASSET_HEADER_SIZE);
|
|
||||||
if(bytesRead != ASSET_HEADER_SIZE) {
|
|
||||||
asset->state = ASSET_STATE_ERROR;
|
|
||||||
zip_fclose(asset->file);
|
|
||||||
asset->file = NULL;
|
|
||||||
errorThrow("Failed to read asset header for: %s", asset->filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check header.
|
|
||||||
if(strlen(header) != ASSET_HEADER_SIZE) {
|
|
||||||
asset->state = ASSET_STATE_ERROR;
|
|
||||||
zip_fclose(asset->file);
|
|
||||||
asset->file = NULL;
|
|
||||||
errorThrow("Invalid asset header for: %s", asset->filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the asset definition based on the header.
|
|
||||||
assetdef_t *def;
|
|
||||||
for(uint_fast8_t i = 0; i < ASSET_TYPE_COUNT; i++) {
|
|
||||||
if(strcmp(header, ASSET_DEFINITIONS[i].header) == 0) {
|
|
||||||
def = &ASSET_DEFINITIONS[i];
|
|
||||||
asset->type = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertNotNull(def, "Failed to find asset definition for header.");
|
|
||||||
|
|
||||||
// Load the asset
|
|
||||||
errorret_t ret = def->load(asset);
|
|
||||||
if(ret.code != ERROR_OK) {
|
|
||||||
asset->state = ASSET_STATE_ERROR;
|
|
||||||
zip_fclose(asset->file);
|
|
||||||
asset->file = NULL;
|
|
||||||
errorChain(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finished loading.
|
|
||||||
asset->state = ASSET_STATE_LOADED;
|
|
||||||
zip_fclose(asset->file);
|
|
||||||
asset->file = NULL;
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t assetDispose(asset_t *asset) {
|
void assetDispose(void) {
|
||||||
assertNotNull(asset, "Asset cannot be NULL.");
|
if(ASSET_MANAGER.zip != NULL) {
|
||||||
|
zip_close(ASSET_MANAGER.zip);
|
||||||
if(asset->state == ASSET_STATE_LOADED) {
|
ASSET_MANAGER.zip = NULL;
|
||||||
// Dispose of the asset based on its type.
|
|
||||||
assetdef_t *def = &ASSET_DEFINITIONS[asset->type];
|
|
||||||
if(def->dispose) errorChain(def->dispose(asset));
|
|
||||||
asset->state = ASSET_STATE_NOT_LOADED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(asset->file) {
|
|
||||||
zip_fclose(asset->file);
|
|
||||||
asset->file = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,98 +7,48 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include "util/reflist.h"
|
|
||||||
#include <zip.h>
|
#include <zip.h>
|
||||||
|
|
||||||
#include "asset/type/assetpaletteimage.h"
|
#if ASSET_TYPE == wad
|
||||||
#include "asset/type/assetalphaimage.h"
|
#else
|
||||||
|
#error "Unsupported ASSET_TYPE"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ASSET_HEADER_SIZE 3
|
#define ASSET_FILE "dusk.dsk"
|
||||||
#define ASSET_REFERENCE_COUNT_MAX 8
|
|
||||||
|
static const char_t *ASSET_SEARCH_PATHS[] = {
|
||||||
|
"%s/%s",
|
||||||
|
"%s",
|
||||||
|
"../%s",
|
||||||
|
"../../%s",
|
||||||
|
"data/%s",
|
||||||
|
"../data/%s",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void (*load)();
|
zip_t *zip;
|
||||||
} assetcallback_t;
|
char_t systemPath[FILENAME_MAX];
|
||||||
|
uint8_t assetCount;
|
||||||
typedef enum {
|
|
||||||
ASSET_STATE_NOT_LOADED,
|
|
||||||
ASSET_STATE_LOADING,
|
|
||||||
ASSET_STATE_LOADED,
|
|
||||||
ASSET_STATE_ERROR,
|
|
||||||
} assetstate_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
ASSET_TYPE_UNKNOWN,
|
|
||||||
ASSET_TYPE_PALETTE_IMAGE,
|
|
||||||
ASSET_TYPE_ALPHA_IMAGE,
|
|
||||||
|
|
||||||
ASSET_TYPE_COUNT
|
|
||||||
} assettype_t;
|
|
||||||
|
|
||||||
typedef struct asset_s {
|
|
||||||
char_t filename[FILENAME_MAX];
|
|
||||||
ref_t refListArray[ASSET_REFERENCE_COUNT_MAX];
|
|
||||||
reflist_t refList;
|
|
||||||
assetstate_t state;
|
|
||||||
assettype_t type;
|
|
||||||
zip_file_t *file;
|
|
||||||
|
|
||||||
union {
|
|
||||||
assetpaletteimage_t paletteImage;
|
|
||||||
assetalphaimage_t alphaImage;
|
|
||||||
};
|
|
||||||
} asset_t;
|
} asset_t;
|
||||||
|
|
||||||
typedef struct {
|
static asset_t ASSET;
|
||||||
const char_t header[ASSET_HEADER_SIZE + 1];
|
|
||||||
errorret_t (*load)(asset_t *asset);
|
|
||||||
errorret_t (*dispose)(asset_t *asset);
|
|
||||||
} assetdef_t;
|
|
||||||
|
|
||||||
extern assetdef_t ASSET_DEFINITIONS[ASSET_TYPE_COUNT];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an asset structure. This should be called by the asset manager
|
* Initializes the asset system.
|
||||||
* only.
|
|
||||||
*
|
|
||||||
* @param asset The asset structure to initialize.
|
|
||||||
* @param filename The filename of the asset.
|
|
||||||
* @return An error code.
|
|
||||||
*/
|
*/
|
||||||
errorret_t assetInit(asset_t *asset, const char_t *filename);
|
errorret_t assetInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests a lock on the given asset. This will increase the reference count
|
* Loads an asset by its filename, the output type depends on the asset type.
|
||||||
* of the asset, and prevent it from being unloaded until all locks are
|
|
||||||
* released.
|
|
||||||
*
|
*
|
||||||
* @param asset The asset to lock.
|
* @param filename The filename of the asset to retrieve.
|
||||||
* @return A unique reference ID for the lock.
|
* @param output The output pointer to store the loaded asset data.
|
||||||
|
* @return An error code if the asset could not be loaded.
|
||||||
*/
|
*/
|
||||||
ref_t assetLock(asset_t *asset);
|
errorret_t assetLoad(const char_t *filename, void *output);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Releases a lock on the given asset. This will decrease the reference count
|
* Disposes/cleans up the asset system.
|
||||||
* of the asset, and allow it to be unloaded if there are no more locks.
|
|
||||||
*
|
|
||||||
* @param asset The asset to unlock.
|
|
||||||
* @param ref The reference ID of the lock to release.
|
|
||||||
*/
|
*/
|
||||||
void assetUnlock(asset_t *asset, const ref_t ref);
|
void assetDispose(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Permission has been granted to load the asset data from disk. This should
|
|
||||||
* only be called by the asset manager.
|
|
||||||
*
|
|
||||||
* @param asset The asset to load.
|
|
||||||
* @return An error code.
|
|
||||||
*/
|
|
||||||
errorret_t assetLoad(asset_t *asset);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disposes of the asset, freeing any allocated memory and closing any open
|
|
||||||
* file handles. This should only be called by the asset manager.
|
|
||||||
*
|
|
||||||
* @param asset The asset to dispose of.
|
|
||||||
*/
|
|
||||||
errorret_t assetDispose(asset_t *asset);
|
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "time/time.h"
|
#include "time/time.h"
|
||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
|
#include "locale/localemanager.h"
|
||||||
#include "display/display.h"
|
#include "display/display.h"
|
||||||
#include "scene/scenemanager.h"
|
#include "scene/scenemanager.h"
|
||||||
#include "asset/assetmanager.h"
|
#include "asset/assetmanager.h"
|
||||||
@@ -27,6 +28,7 @@ errorret_t engineInit(void) {
|
|||||||
// Init systems. Order is important.
|
// Init systems. Order is important.
|
||||||
timeInit();
|
timeInit();
|
||||||
inputInit();
|
inputInit();
|
||||||
|
localeManagerInit();
|
||||||
errorChain(assetManagerInit());
|
errorChain(assetManagerInit());
|
||||||
errorChain(displayInit());
|
errorChain(displayInit());
|
||||||
errorChain(uiInit());
|
errorChain(uiInit());
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ typedef struct {
|
|||||||
errorstate_t *state;
|
errorstate_t *state;
|
||||||
} errorret_t;
|
} errorret_t;
|
||||||
|
|
||||||
|
|
||||||
static const errorcode_t ERROR_OK = 0;
|
static const errorcode_t ERROR_OK = 0;
|
||||||
static const errorcode_t ERROR_NOT_OK = 1;
|
static const errorcode_t ERROR_NOT_OK = 1;
|
||||||
|
|
||||||
|
|||||||
@@ -6,5 +6,5 @@
|
|||||||
# Sources
|
# Sources
|
||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
language.c
|
localemanager.c
|
||||||
)
|
)
|
||||||
15
src/locale/localemanager.c
Normal file
15
src/locale/localemanager.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "localemanager.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
|
||||||
|
localemanager_t LOCALE;
|
||||||
|
|
||||||
|
void localeManagerInit() {
|
||||||
|
memoryZero(&LOCALE, sizeof(localemanager_t));
|
||||||
|
}
|
||||||
20
src/locale/localemanager.h
Normal file
20
src/locale/localemanager.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
void *nothing;
|
||||||
|
} localemanager_t;
|
||||||
|
|
||||||
|
extern localemanager_t LOCALE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the locale system.
|
||||||
|
*/
|
||||||
|
void localeManagerInit();
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "engine/engine.h"
|
#include "engine/engine.h"
|
||||||
#include "asset/assetmanager.h"
|
#include "asset/asset.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
|
|
||||||
@@ -23,8 +23,8 @@ int main(int argc, char **argv) {
|
|||||||
// Setup system path on asset manager
|
// Setup system path on asset manager
|
||||||
if(argc > 0) {
|
if(argc > 0) {
|
||||||
stringCopy(
|
stringCopy(
|
||||||
ASSET_MANAGER.systemPath, argv[0],
|
ASSET.systemPath, argv[0],
|
||||||
sizeof(ASSET_MANAGER.systemPath) / sizeof(char_t)
|
sizeof(ASSET.systemPath) / sizeof(char_t)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
#include "asset/assetmanager.h"
|
#include "asset/asset.h"
|
||||||
#include "display/tileset/tileset.h"
|
#include "display/tileset/tileset.h"
|
||||||
#include "display/camera.h"
|
#include "display/camera.h"
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "asset/assetmanager.h"
|
#include "asset/asset.h"
|
||||||
#include "display/tileset/tileset_minogram.h"
|
#include "display/tileset/tileset_minogram.h"
|
||||||
|
|
||||||
#define UI_TEXT_CHAR_START '!'
|
#define UI_TEXT_CHAR_START '!'
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ def processPalette(asset):
|
|||||||
|
|
||||||
# PSP requires that the palette size be a power of two, so we will pad the
|
# PSP requires that the palette size be a power of two, so we will pad the
|
||||||
# palette with transparent colors if needed.
|
# palette with transparent colors if needed.
|
||||||
# if args.platform == "psp":
|
|
||||||
def mathNextPowTwo(x):
|
def mathNextPowTwo(x):
|
||||||
return 1 << (x - 1).bit_length()
|
return 1 << (x - 1).bit_length()
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ def processPalette(asset):
|
|||||||
data += f"static const color_t PALETTE_{paletteIndex}_COLORS[PALETTE_{paletteIndex}_COLOR_COUNT] = {{\n"
|
data += f"static const color_t PALETTE_{paletteIndex}_COLORS[PALETTE_{paletteIndex}_COLOR_COUNT] = {{\n"
|
||||||
for pixel in pixels:
|
for pixel in pixels:
|
||||||
data += f" {{ 0x{pixel[0]:02X}, 0x{pixel[1]:02X}, 0x{pixel[2]:02X}, 0x{pixel[3]:02X} }},\n"
|
data += f" {{ 0x{pixel[0]:02X}, 0x{pixel[1]:02X}, 0x{pixel[2]:02X}, 0x{pixel[3]:02X} }},\n"
|
||||||
data += f"}};\n\n"
|
data += f"}};\n"
|
||||||
data += f"#pragma pack(pop)\n\n"
|
data += f"#pragma pack(pop)\n\n"
|
||||||
data += f"static const palette_t PALETTE_{paletteIndex} = {{\n"
|
data += f"static const palette_t PALETTE_{paletteIndex} = {{\n"
|
||||||
data += f" .colorCount = PALETTE_{paletteIndex}_COLOR_COUNT,\n"
|
data += f" .colorCount = PALETTE_{paletteIndex}_COLOR_COUNT,\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user