Palette loading done.
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
asset.c
|
asset.c
|
||||||
|
assetpalette.c
|
||||||
|
assettileset.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Compile definitions
|
# Compile definitions
|
||||||
|
@@ -55,7 +55,11 @@ errorret_t assetInit(void) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void assetLoad(const char_t *filename) {
|
void assetLoad(
|
||||||
|
const char_t *filename,
|
||||||
|
void (*callback)(void* data),
|
||||||
|
void *data
|
||||||
|
) {
|
||||||
assertNotNull(filename, "Filename cannot be NULL.");
|
assertNotNull(filename, "Filename cannot be NULL.");
|
||||||
assertTrue(strlen(filename) < ASSET_FILENAME_MAX, "Filename too long.");
|
assertTrue(strlen(filename) < ASSET_FILENAME_MAX, "Filename too long.");
|
||||||
assertTrue(strlen(filename) > 0, "Filename cannot be empty.");
|
assertTrue(strlen(filename) > 0, "Filename cannot be empty.");
|
||||||
@@ -74,6 +78,8 @@ void assetLoad(const char_t *filename) {
|
|||||||
assertNotNull(expected->extension, "Unknown asset type.");
|
assertNotNull(expected->extension, "Unknown asset type.");
|
||||||
|
|
||||||
// Pass off to the thread to begin loading.
|
// Pass off to the thread to begin loading.
|
||||||
|
ASSET.callback = callback;
|
||||||
|
ASSET.callbackData = data;
|
||||||
ASSET.errorState = ERROR_STATE_INIT;
|
ASSET.errorState = ERROR_STATE_INIT;
|
||||||
ASSET.state = ASSET_STATE_LOADING;
|
ASSET.state = ASSET_STATE_LOADING;
|
||||||
stringCopy(ASSET.filename, filename, ASSET_FILENAME_MAX);
|
stringCopy(ASSET.filename, filename, ASSET_FILENAME_MAX);
|
||||||
@@ -88,6 +94,7 @@ void assetLoad(const char_t *filename) {
|
|||||||
"Failed to open asset: %s",
|
"Failed to open asset: %s",
|
||||||
filename
|
filename
|
||||||
);
|
);
|
||||||
|
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,11 +108,13 @@ void assetLoad(const char_t *filename) {
|
|||||||
"Failed to stat asset: %s",
|
"Failed to stat asset: %s",
|
||||||
filename
|
filename
|
||||||
);
|
);
|
||||||
|
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(st.size > sizeof(ASSET.data.palette)) {
|
if(st.size > sizeof(ASSET.data.palette)) {
|
||||||
zip_fclose(file);
|
zip_fclose(file);
|
||||||
|
ASSET.state = ASSET_STATE_ERROR;
|
||||||
ASSET.error = errorCreate(
|
ASSET.error = errorCreate(
|
||||||
&ASSET.errorState,
|
&ASSET.errorState,
|
||||||
"Asset size mismatch: %s (got %d, expected %d)",
|
"Asset size mismatch: %s (got %d, expected %d)",
|
||||||
@@ -113,6 +122,7 @@ void assetLoad(const char_t *filename) {
|
|||||||
(int)st.size,
|
(int)st.size,
|
||||||
(int)sizeof(ASSET.data.palette)
|
(int)sizeof(ASSET.data.palette)
|
||||||
);
|
);
|
||||||
|
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,10 +146,16 @@ void assetLoad(const char_t *filename) {
|
|||||||
expected->header[1],
|
expected->header[1],
|
||||||
expected->header[2]
|
expected->header[2]
|
||||||
);
|
);
|
||||||
|
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parse the asset.
|
||||||
|
assertNotNull(expected->parser, "Asset parser cannot be NULL.");
|
||||||
|
expected->parser();
|
||||||
|
|
||||||
printf("Loaded asset: %s\n", filename);
|
printf("Loaded asset: %s\n", filename);
|
||||||
|
if(ASSET.callback) ASSET.callback(ASSET.callbackData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void assetDispose(void) {
|
void assetDispose(void) {
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include "assettileset.h"
|
#include "assettileset.h"
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
#include <zip.h>
|
#include <zip.h>
|
||||||
|
#include "display/texture/texture.h"
|
||||||
|
|
||||||
#define ASSET_COUNT_MAX 128
|
#define ASSET_COUNT_MAX 128
|
||||||
#define ASSET_FILENAME_MAX 128
|
#define ASSET_FILENAME_MAX 128
|
||||||
@@ -21,6 +22,7 @@
|
|||||||
#error "Unsupported ASSET_TYPE"
|
#error "Unsupported ASSET_TYPE"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char_t header[ASSET_HEADER_LENGTH];
|
char_t header[ASSET_HEADER_LENGTH];
|
||||||
union {
|
union {
|
||||||
@@ -28,6 +30,14 @@ typedef struct {
|
|||||||
assettileset_t tileset;
|
assettileset_t tileset;
|
||||||
};
|
};
|
||||||
} assetdata_t;
|
} assetdata_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
texture_t palette;
|
||||||
|
assettileset_t *tileset;
|
||||||
|
};
|
||||||
|
} assetloaded_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ASSET_STATE_NONE,
|
ASSET_STATE_NONE,
|
||||||
@@ -46,11 +56,16 @@ typedef struct {
|
|||||||
assetstate_t state;
|
assetstate_t state;
|
||||||
char_t filename[ASSET_FILENAME_MAX];
|
char_t filename[ASSET_FILENAME_MAX];
|
||||||
assetdata_t data;
|
assetdata_t data;
|
||||||
|
assetloaded_t loaded;
|
||||||
|
|
||||||
|
void (*callback)(void* data);
|
||||||
|
void *callbackData;
|
||||||
} asset_t;
|
} asset_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char_t *header;
|
const char_t *header;
|
||||||
const char_t *extension;
|
const char_t *extension;
|
||||||
|
void (*parser)();
|
||||||
} assetmap_t;
|
} assetmap_t;
|
||||||
|
|
||||||
static const char_t ASSET_SEARCH_PATHS[][FILENAME_MAX] = {
|
static const char_t ASSET_SEARCH_PATHS[][FILENAME_MAX] = {
|
||||||
@@ -63,9 +78,9 @@ static const char_t ASSET_SEARCH_PATHS[][FILENAME_MAX] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const assetmap_t ASSET_MAP[] = {
|
static const assetmap_t ASSET_MAP[] = {
|
||||||
{ "DPF", "test.palette.dpf" },
|
{ "DPF", ".dpf", assetParsePalette },
|
||||||
{ "DPT", "test.tileset.dpt" },
|
{ "DPT", ".dpt", assetParseTileset },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ASSET_SEARCH_PATHS_COUNT (\
|
#define ASSET_SEARCH_PATHS_COUNT (\
|
||||||
@@ -83,9 +98,15 @@ errorret_t assetInit(void);
|
|||||||
* Gets an asset by filename, does not load it.
|
* Gets an asset by filename, does not load it.
|
||||||
*
|
*
|
||||||
* @param filename The filename of the asset to get.
|
* @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.
|
* @return The asset.
|
||||||
*/
|
*/
|
||||||
void assetLoad(const char_t *filename);
|
void assetLoad(
|
||||||
|
const char_t *filename,
|
||||||
|
void (*callback)(void* data),
|
||||||
|
void *data
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disposes/cleans up the asset system.
|
* Disposes/cleans up the asset system.
|
||||||
|
18
src/asset/assetpalette.c
Normal file
18
src/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
|
||||||
|
);
|
||||||
|
}
|
@@ -15,3 +15,8 @@ typedef struct {
|
|||||||
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the palette from the loaded raw data.
|
||||||
|
*/
|
||||||
|
void assetParsePalette();
|
12
src/asset/assettileset.c
Normal file
12
src/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;
|
||||||
|
}
|
@@ -17,3 +17,8 @@ typedef struct {
|
|||||||
int32_t columns;
|
int32_t columns;
|
||||||
char_t tilesetName[256];
|
char_t tilesetName[256];
|
||||||
} assettileset_t;
|
} assettileset_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the tileset from the loaded raw data.
|
||||||
|
*/
|
||||||
|
void assetParseTileset();
|
@@ -18,6 +18,12 @@
|
|||||||
|
|
||||||
engine_t ENGINE;
|
engine_t ENGINE;
|
||||||
|
|
||||||
|
void assetLoadCallback(void *data) {
|
||||||
|
consolePrint("Asset load callback called!");
|
||||||
|
test = ASSET.loaded.palette;
|
||||||
|
consolePrint("Loaded palette with %d colors", ASSET.data.palette.colorCount);
|
||||||
|
}
|
||||||
|
|
||||||
errorret_t engineInit(void) {
|
errorret_t engineInit(void) {
|
||||||
memoryZero(&ENGINE, sizeof(engine_t));
|
memoryZero(&ENGINE, sizeof(engine_t));
|
||||||
ENGINE.running = true;
|
ENGINE.running = true;
|
||||||
@@ -29,8 +35,7 @@ errorret_t engineInit(void) {
|
|||||||
errorChain(assetInit());
|
errorChain(assetInit());
|
||||||
errorChain(displayInit());
|
errorChain(displayInit());
|
||||||
|
|
||||||
// assetLoad("test.palette.dp123123");
|
assetLoad("test.palette.dpf", assetLoadCallback, NULL);
|
||||||
assetLoad("test.palette.dpf");
|
|
||||||
if(ASSET.state == ASSET_STATE_ERROR) errorChain(ASSET.error);
|
if(ASSET.state == ASSET_STATE_ERROR) errorChain(ASSET.error);
|
||||||
|
|
||||||
sceneTestAdd();
|
sceneTestAdd();
|
||||||
|
@@ -28,11 +28,11 @@ void sceneTestAdd(void) {
|
|||||||
);
|
);
|
||||||
nodeMatrixSet(camera, lookAt);
|
nodeMatrixSet(camera, lookAt);
|
||||||
|
|
||||||
color4b_t pixels[4] = {
|
// color4b_t pixels[4] = {
|
||||||
COLOR_RED, COLOR_GREEN,
|
// COLOR_RED, COLOR_GREEN,
|
||||||
COLOR_BLUE, COLOR_WHITE
|
// COLOR_BLUE, COLOR_WHITE
|
||||||
};
|
// };
|
||||||
textureInit(&test, 2, 2, TEXTURE_FORMAT_RGBA, pixels);
|
// textureInit(&test, 2, 2, TEXTURE_FORMAT_RGBA, pixels);
|
||||||
|
|
||||||
// Test cube
|
// Test cube
|
||||||
ecsid_t cube = ecsEntityAdd();
|
ecsid_t cube = ecsEntityAdd();
|
||||||
|
@@ -7,5 +7,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "ecs/ecssystem.h"
|
#include "ecs/ecssystem.h"
|
||||||
|
#include "display/texture/texture.h"
|
||||||
|
|
||||||
|
extern texture_t test;
|
||||||
|
|
||||||
void sceneTestAdd(void);
|
void sceneTestAdd(void);
|
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
from args import args
|
from args import args
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
import struct
|
||||||
|
|
||||||
def extractPaletteFromImage(image):
|
def extractPaletteFromImage(image):
|
||||||
# goes through and finds all unique colors in the image
|
# goes through and finds all unique colors in the image
|
||||||
@@ -14,19 +15,14 @@ def extractPaletteFromImage(image):
|
|||||||
return uniqueColors
|
return uniqueColors
|
||||||
|
|
||||||
def savePalette(pixels, outputFilePath):
|
def savePalette(pixels, outputFilePath):
|
||||||
# Pixels is a list of (R, G, B, A) tuples
|
|
||||||
data = "DPF" # Header for Dusk Palette Format
|
|
||||||
|
|
||||||
# Count of colors (int32_t)
|
|
||||||
colorCount = len(pixels)
|
colorCount = len(pixels)
|
||||||
data += colorCount.to_bytes(4, byteorder='little').decode('latin1')
|
buf = bytearray(b"DPF")
|
||||||
|
buf += struct.pack("<i", colorCount) # little-endian int32_t
|
||||||
for r, g, b, a in pixels:
|
for r, g, b, a in pixels: # each channel 0..255
|
||||||
data += bytes([r, g, b, a]).decode('latin1')
|
buf += struct.pack("BBBB", r, g, b, a) # raw bytes
|
||||||
|
|
||||||
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
|
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
|
||||||
with open(outputFilePath, 'wb') as f:
|
with open(outputFilePath, "wb") as f:
|
||||||
f.write(data.encode('latin1'))
|
f.write(buf)
|
||||||
|
|
||||||
def processPalette(assetPath):
|
def processPalette(assetPath):
|
||||||
# Process the image file
|
# Process the image file
|
||||||
|
Reference in New Issue
Block a user