commit asset prog
This commit is contained in:
@@ -7,7 +7,6 @@
|
|||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
asset.c
|
asset.c
|
||||||
assetsystem.c
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Compile definitions
|
# Compile definitions
|
||||||
|
@@ -6,7 +6,127 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "asset.h"
|
#include "asset.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
void assetInit() {
|
#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.");
|
||||||
|
|
||||||
|
// Get "test.palette.dpf" file.
|
||||||
|
zip_file_t *file = zip_fopen(ASSET.zip, "test.palette.dpf", 0);
|
||||||
|
if(file == NULL) errorThrow("Failed to open test.palette.dpf in asset file.");
|
||||||
|
|
||||||
|
// Read it
|
||||||
|
char_t buffer[256];
|
||||||
|
zip_int64_t n = zip_fread(file, buffer, 256);
|
||||||
|
if(n < 0) {
|
||||||
|
zip_fclose(file);
|
||||||
|
errorThrow("Failed to read test.palette.dpf in asset file.");
|
||||||
|
}
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetLoad(const char_t *filename) {
|
||||||
|
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."
|
||||||
|
);
|
||||||
|
|
||||||
|
// Pass off to the thread to begin loading.
|
||||||
|
ASSET.errorState = ERROR_STATE_INIT;
|
||||||
|
ASSET.state = ASSET_STATE_LOADING;
|
||||||
|
stringCopy(ASSET.filename, filename, ASSET_FILENAME_MAX);
|
||||||
|
memoryZero(&ASSET.data, sizeof(ASSET.data));
|
||||||
|
|
||||||
|
consolePrint("Loading asset: %s", filename);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
consolePrint("Opened asset: %s", 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
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Asset size: %d\n", (int)st.size);
|
||||||
|
if(st.size > sizeof(ASSET.data.palette)) {
|
||||||
|
zip_fclose(file);
|
||||||
|
ASSET.error = errorCreate(
|
||||||
|
&ASSET.errorState,
|
||||||
|
"Asset size mismatch: %s (got %d, expected %d)",
|
||||||
|
filename,
|
||||||
|
(int)st.size,
|
||||||
|
(int)sizeof(ASSET.data.palette)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read entire file into the asset data.
|
||||||
|
zip_fread(file, &ASSET.data, st.size);
|
||||||
|
zip_fclose(file);
|
||||||
|
ASSET.state = ASSET_STATE_LOADED;
|
||||||
|
consolePrint("First 3 bytes: %c%c%c\n",
|
||||||
|
ASSET.data.header[0],
|
||||||
|
ASSET.data.header[1],
|
||||||
|
ASSET.data.header[2]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetDispose(void) {
|
||||||
|
if(ASSET.zip != NULL) {
|
||||||
|
zip_close(ASSET.zip);
|
||||||
|
ASSET.zip = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
@@ -7,19 +7,75 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
|
#include "assetpalette.h"
|
||||||
|
#include "assettileset.h"
|
||||||
|
#include "error/error.h"
|
||||||
#include <zip.h>
|
#include <zip.h>
|
||||||
|
|
||||||
#define ASSET_FILENAME_MAX 256
|
#define ASSET_COUNT_MAX 128
|
||||||
|
#define ASSET_FILENAME_MAX 128
|
||||||
|
|
||||||
typedef struct asset_s {
|
#if ASSET_TYPE == wad
|
||||||
|
#else
|
||||||
|
#error "Unsupported ASSET_TYPE"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char_t header[3];
|
||||||
|
union {
|
||||||
|
assetpalette_t palette;
|
||||||
|
assettileset_t tileset;
|
||||||
|
};
|
||||||
|
} assetdata_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ASSET_STATE_NONE,
|
||||||
|
ASSET_STATE_LOADING,
|
||||||
|
ASSET_STATE_LOADED,
|
||||||
|
ASSET_STATE_ERROR
|
||||||
|
} assetstate_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
int32_t nothing;
|
int32_t nothing;
|
||||||
|
zip_t *zip;
|
||||||
|
// thread_t thread;
|
||||||
|
|
||||||
const char_t *filename;
|
errorstate_t errorState;
|
||||||
zip_file_t *fileHandle;
|
errorret_t error;
|
||||||
|
assetstate_t state;
|
||||||
|
char_t filename[ASSET_FILENAME_MAX];
|
||||||
|
assetdata_t data;
|
||||||
} asset_t;
|
} asset_t;
|
||||||
|
|
||||||
void assetInit(
|
static const char_t ASSET_SEARCH_PATHS[][FILENAME_MAX] = {
|
||||||
const char_t *filename,
|
"%s/%s",
|
||||||
);
|
"./%s",
|
||||||
|
"../%s",
|
||||||
|
"../../%s",
|
||||||
|
"data/%s",
|
||||||
|
"../data/%s",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ASSET_SEARCH_PATHS_COUNT (\
|
||||||
|
sizeof(ASSET_SEARCH_PATHS) / FILENAME_MAX\
|
||||||
|
)
|
||||||
|
|
||||||
|
extern asset_t ASSET;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the asset system.
|
||||||
|
*/
|
||||||
|
errorret_t assetInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an asset by filename, does not load it.
|
||||||
|
*
|
||||||
|
* @param filename The filename of the asset to get.
|
||||||
|
* @return The asset.
|
||||||
|
*/
|
||||||
|
void assetLoad(const char_t *filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes/cleans up the asset system.
|
||||||
|
*/
|
||||||
void assetDispose(void);
|
void assetDispose(void);
|
@@ -12,7 +12,6 @@
|
|||||||
#define ASSET_PALETTE_COLOR_COUNT_MAX 256
|
#define ASSET_PALETTE_COLOR_COUNT_MAX 256
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char_t header[3];
|
|
||||||
int32_t colorCount;
|
int32_t colorCount;
|
||||||
color4b_t colors[ASSET_PALETTE_COLOR_COUNT_MAX];
|
color4b_t colors[ASSET_PALETTE_COLOR_COUNT_MAX];
|
||||||
} assetpalette_t;
|
} assetpalette_t;
|
@@ -1,74 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "assetsystem.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "console/console.h"
|
|
||||||
|
|
||||||
#define ASSET_SYSTEM_ASSET_FILE "dusk.dsk"
|
|
||||||
|
|
||||||
const char_t ASSET_SYSTEM_SEARCH_PATHS[][FILENAME_MAX] = {
|
|
||||||
"%s/%s",
|
|
||||||
"./%s",
|
|
||||||
"../%s",
|
|
||||||
"../../%s",
|
|
||||||
"data/%s",
|
|
||||||
"../data/%s",
|
|
||||||
};
|
|
||||||
#define ASSET_SYSTEM_SEARCH_PATHS_COUNT (\
|
|
||||||
sizeof(ASSET_SYSTEM_SEARCH_PATHS) / FILENAME_MAX\
|
|
||||||
)
|
|
||||||
|
|
||||||
assetsystem_t ASSET_SYSTEM;
|
|
||||||
|
|
||||||
errorret_t assetSystemInit(void) {
|
|
||||||
memoryZero(&ASSET_SYSTEM, sizeof(assetsystem_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_SYSTEM_SEARCH_PATHS_COUNT; i++) {
|
|
||||||
sprintf(
|
|
||||||
searchPath,
|
|
||||||
ASSET_SYSTEM_SEARCH_PATHS[i],
|
|
||||||
sysPath,
|
|
||||||
ASSET_SYSTEM_ASSET_FILE
|
|
||||||
);
|
|
||||||
|
|
||||||
// Try open
|
|
||||||
ASSET_SYSTEM.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
|
|
||||||
if(ASSET_SYSTEM.zip == NULL) continue;
|
|
||||||
consolePrint("Opened asset file: %s", searchPath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Did we open the asset?
|
|
||||||
if(ASSET_SYSTEM.zip == NULL) errorThrow("Failed to open asset file.");
|
|
||||||
|
|
||||||
// Get "test.palette.dpf" file.
|
|
||||||
zip_file_t *file = zip_fopen(ASSET_SYSTEM.zip, "test.palette.dpf", 0);
|
|
||||||
if(file == NULL) errorThrow("Failed to open test.palette.dpf in asset file.");
|
|
||||||
|
|
||||||
// Read it
|
|
||||||
char_t buffer[256];
|
|
||||||
zip_int64_t n = zip_fread(file, buffer, 256);
|
|
||||||
if(n < 0) {
|
|
||||||
zip_fclose(file);
|
|
||||||
errorThrow("Failed to read test.palette.dpf in asset file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
void assetSystemDispose(void) {
|
|
||||||
if(ASSET_SYSTEM.zip != NULL) {
|
|
||||||
zip_close(ASSET_SYSTEM.zip);
|
|
||||||
ASSET_SYSTEM.zip = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2025 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "asset.h"
|
|
||||||
#include "error/error.h"
|
|
||||||
|
|
||||||
#if ASSET_TYPE == wad
|
|
||||||
#else
|
|
||||||
#error "Unsupported ASSET_TYPE"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int32_t nothing;
|
|
||||||
zip_t *zip;
|
|
||||||
} assetsystem_t;
|
|
||||||
|
|
||||||
extern assetsystem_t ASSET_SYSTEM;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the asset system.
|
|
||||||
*/
|
|
||||||
errorret_t assetSystemInit(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disposes/cleans up the asset system.
|
|
||||||
*/
|
|
||||||
void assetSystemDispose(void);
|
|
@@ -11,7 +11,6 @@
|
|||||||
typedef struct assetimage_s assetimage_t;
|
typedef struct assetimage_s assetimage_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char_t header[3];
|
|
||||||
int32_t tileWidth;
|
int32_t tileWidth;
|
||||||
int32_t tileHeight;
|
int32_t tileHeight;
|
||||||
int32_t tileCount;
|
int32_t tileCount;
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
#include "display/display.h"
|
#include "display/display.h"
|
||||||
#include "ecs/ecssystem.h"
|
#include "ecs/ecssystem.h"
|
||||||
#include "scene/node.h"
|
#include "scene/node.h"
|
||||||
#include "asset/assetsystem.h"
|
#include "asset/asset.h"
|
||||||
|
|
||||||
#include "scene/test/scenetest.h"
|
#include "scene/test/scenetest.h"
|
||||||
|
|
||||||
@@ -26,8 +26,12 @@ errorret_t engineInit(void) {
|
|||||||
timeInit();
|
timeInit();
|
||||||
consoleInit();
|
consoleInit();
|
||||||
ecsSystemInit();
|
ecsSystemInit();
|
||||||
errorChain(assetSystemInit());
|
errorChain(assetInit());
|
||||||
errorChain(displayInit());
|
errorChain(displayInit());
|
||||||
|
|
||||||
|
assetLoad("test.palette.dp123123");
|
||||||
|
// assetLoad("test.palette.dpf");
|
||||||
|
if(ASSET.state == ASSET_STATE_ERROR) errorChain(ASSET.error);
|
||||||
|
|
||||||
sceneTestAdd();
|
sceneTestAdd();
|
||||||
|
|
||||||
@@ -45,7 +49,7 @@ errorret_t engineUpdate(void) {
|
|||||||
errorret_t engineDispose(void) {
|
errorret_t engineDispose(void) {
|
||||||
ecsSystemDispose();
|
ecsSystemDispose();
|
||||||
errorChain(displayDispose());
|
errorChain(displayDispose());
|
||||||
assetSystemDispose();
|
assetDispose();
|
||||||
consoleDispose();
|
consoleDispose();
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
@@ -21,15 +21,15 @@ 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;
|
||||||
|
|
||||||
|
#define ERROR_STATE_INIT ((errorstate_t){ ERROR_OK, NULL, NULL })
|
||||||
|
|
||||||
static const char_t *ERROR_PRINT_FORMAT = "Error (%d): %s\n%s";
|
static const char_t *ERROR_PRINT_FORMAT = "Error (%d): %s\n%s";
|
||||||
static const char_t *ERROR_LINE_FORMAT = " at %s:%d in function %s\n";
|
static const char_t *ERROR_LINE_FORMAT = " at %s:%d in function %s\n";
|
||||||
static errorstate_t ERROR_STATE = {
|
static errorstate_t ERROR_STATE = ERROR_STATE_INIT;
|
||||||
.code = ERROR_OK,
|
|
||||||
.message = NULL,
|
|
||||||
.lines = NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the error state with the provided code and message.
|
* Sets the error state with the provided code and message.
|
||||||
@@ -91,6 +91,34 @@ void errorCatch(const errorret_t retval);
|
|||||||
*/
|
*/
|
||||||
errorret_t errorPrint(const errorret_t retval);
|
errorret_t errorPrint(const errorret_t retval);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an error with a specific error state.
|
||||||
|
*
|
||||||
|
* @param state The error state to set.
|
||||||
|
* @param message The format string for the error message.
|
||||||
|
* @param ... Additional arguments for the format string.
|
||||||
|
* @return The error code.
|
||||||
|
*/
|
||||||
|
#define errorCreate(state, message, ... ) \
|
||||||
|
errorThrowImpl(\
|
||||||
|
(state), ERROR_NOT_OK, __FILE__, __func__, __LINE__, (message), \
|
||||||
|
##__VA_ARGS__ \
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws an error with a specific error state.
|
||||||
|
*
|
||||||
|
* @param state The error state to set.
|
||||||
|
* @param message The format string for the error message.
|
||||||
|
* @param ... Additional arguments for the format string.
|
||||||
|
* @return The error code.
|
||||||
|
*/
|
||||||
|
#define errorThrowState(state, message, ... ) \
|
||||||
|
return errorThrowImpl(\
|
||||||
|
(state), ERROR_NOT_OK, __FILE__, __func__, __LINE__, (message), \
|
||||||
|
##__VA_ARGS__ \
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an error with a formatted message.
|
* Throws an error with a formatted message.
|
||||||
*
|
*
|
||||||
|
@@ -125,4 +125,14 @@ bool_t stringToU16(const char_t *str, uint16_t *out) {
|
|||||||
}
|
}
|
||||||
*out = (uint16_t)result;
|
*out = (uint16_t)result;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t stringEndsWith(const char_t *str, const char_t *suffix) {
|
||||||
|
assertNotNull(str, "str must not be NULL");
|
||||||
|
assertNotNull(suffix, "suffix must not be NULL");
|
||||||
|
|
||||||
|
size_t strLen = strlen(str);
|
||||||
|
size_t suffixLen = strlen(suffix);
|
||||||
|
if(suffixLen > strLen) return false;
|
||||||
|
return strcmp(str + strLen - suffixLen, suffix) == 0;
|
||||||
}
|
}
|
@@ -115,4 +115,13 @@ bool_t stringToI16(const char_t *str, int16_t *out);
|
|||||||
* @param out The output unsigned integer.
|
* @param out The output unsigned integer.
|
||||||
* @return TRUE if the conversion was successful, FALSE otherwise.
|
* @return TRUE if the conversion was successful, FALSE otherwise.
|
||||||
*/
|
*/
|
||||||
bool_t stringToU16(const char_t *str, uint16_t *out);
|
bool_t stringToU16(const char_t *str, uint16_t *out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a string ends with a specified suffix.
|
||||||
|
*
|
||||||
|
* @param str The string to check.
|
||||||
|
* @param suffix The suffix to check for.
|
||||||
|
* @return TRUE if the string ends with the suffix, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
bool_t stringEndsWith(const char_t *str, const char_t *suffix);
|
Reference in New Issue
Block a user