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
|
||||||
|
)
|
@@ -4,6 +4,7 @@
|
|||||||
# https://opensource.org/licenses/MIT
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
add_asset(PALETTE first.palette.png)
|
add_asset(PALETTE first.palette.png)
|
||||||
|
add_asset(IMAGE minogram_6x10.png type=ALPHA)
|
||||||
|
add_asset(IMAGE entities.png type=PALETTIZED)
|
||||||
|
|
||||||
# add_asset(TILESET entities.tsx)
|
# add_asset(TILESET entities.tsx)
|
||||||
# add_asset(IMAGE minogram_6x10.png)
|
|
@@ -6,14 +6,5 @@
|
|||||||
# Sources
|
# Sources
|
||||||
target_sources(${DUSK_TARGET_NAME}
|
target_sources(${DUSK_TARGET_NAME}
|
||||||
PRIVATE
|
PRIVATE
|
||||||
asset.c
|
assetmanager.c
|
||||||
assetpalette.c
|
|
||||||
assettileset.c
|
|
||||||
assetpaletteimage.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Compile definitions
|
|
||||||
target_compile_definitions(${DUSK_TARGET_NAME}
|
|
||||||
PRIVATE
|
|
||||||
ASSET_TYPE=wad
|
|
||||||
)
|
)
|
51
src/asset/assetmanager.c
Normal file
51
src/asset/assetmanager.c
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2025 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "assetmanager.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "console/console.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
#define ASSET_ASSET_FILE "dusk.dsk"
|
||||||
|
|
||||||
|
assetmanager_t ASSET_MANAGER;
|
||||||
|
|
||||||
|
errorret_t assetManagerInit(void) {
|
||||||
|
memoryZero(&ASSET_MANAGER, sizeof(assetmanager_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_MANAGER_SEARCH_PATHS_COUNT; i++) {
|
||||||
|
sprintf(
|
||||||
|
searchPath,
|
||||||
|
ASSET_MANAGER_SEARCH_PATHS[i],
|
||||||
|
sysPath,
|
||||||
|
ASSET_ASSET_FILE
|
||||||
|
);
|
||||||
|
|
||||||
|
// Try open
|
||||||
|
ASSET_MANAGER.zip = zip_open(searchPath, ZIP_RDONLY, NULL);
|
||||||
|
if(ASSET_MANAGER.zip == NULL) continue;
|
||||||
|
consolePrint("Opened asset file: %s", searchPath);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Did we open the asset?
|
||||||
|
if(ASSET_MANAGER.zip == NULL) errorThrow("Failed to open asset file.");
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void assetManagerDispose(void) {
|
||||||
|
if(ASSET_MANAGER.zip != NULL) {
|
||||||
|
zip_close(ASSET_MANAGER.zip);
|
||||||
|
ASSET_MANAGER.zip = NULL;
|
||||||
|
}
|
||||||
|
}
|
46
src/asset/assetmanager.h
Normal file
46
src/asset/assetmanager.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* 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 <zip.h>
|
||||||
|
#include "display/texture/texture.h"
|
||||||
|
|
||||||
|
#if ASSET_TYPE == wad
|
||||||
|
#else
|
||||||
|
#error "Unsupported ASSET_TYPE"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const char_t ASSET_MANAGER_SEARCH_PATHS[][FILENAME_MAX] = {
|
||||||
|
"%s/%s",
|
||||||
|
"./%s",
|
||||||
|
"../%s",
|
||||||
|
"../../%s",
|
||||||
|
"data/%s",
|
||||||
|
"../data/%s",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ASSET_MANAGER_SEARCH_PATHS_COUNT (\
|
||||||
|
sizeof(ASSET_MANAGER_SEARCH_PATHS) / FILENAME_MAX\
|
||||||
|
)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t nothing;
|
||||||
|
zip_t *zip;
|
||||||
|
} assetmanager_t;
|
||||||
|
|
||||||
|
extern assetmanager_t ASSET_MANAGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the asset system.
|
||||||
|
*/
|
||||||
|
errorret_t assetManagerInit(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes/cleans up the asset system.
|
||||||
|
*/
|
||||||
|
void assetManagerDispose(void);
|
@@ -10,7 +10,7 @@
|
|||||||
#include "time/time.h"
|
#include "time/time.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "display/display.h"
|
#include "display/display.h"
|
||||||
#include "asset/asset.h"
|
#include "asset/assetmanager.h"
|
||||||
#include "rpg/rpg.h"
|
#include "rpg/rpg.h"
|
||||||
|
|
||||||
engine_t ENGINE;
|
engine_t ENGINE;
|
||||||
@@ -22,7 +22,7 @@ errorret_t engineInit(void) {
|
|||||||
// Init systems. Order is important.
|
// Init systems. Order is important.
|
||||||
timeInit();
|
timeInit();
|
||||||
consoleInit();
|
consoleInit();
|
||||||
errorChain(assetInit());
|
errorChain(assetManagerInit());
|
||||||
errorChain(displayInit());
|
errorChain(displayInit());
|
||||||
rpgInit();
|
rpgInit();
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ errorret_t engineUpdate(void) {
|
|||||||
|
|
||||||
errorret_t engineDispose(void) {
|
errorret_t engineDispose(void) {
|
||||||
errorChain(displayDispose());
|
errorChain(displayDispose());
|
||||||
assetDispose();
|
assetManagerDispose();
|
||||||
consoleDispose();
|
consoleDispose();
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import sys
|
import sys
|
||||||
# from processtileset import processTileset
|
# from processtileset import processTileset
|
||||||
# from processimage import processPalette, processImage
|
from processimage import processImage
|
||||||
from processpalette import processPalette
|
from processpalette import processPalette
|
||||||
|
|
||||||
processedAssets = []
|
processedAssets = []
|
||||||
@@ -15,8 +15,8 @@ def processAsset(asset):
|
|||||||
t = asset['type'].lower()
|
t = asset['type'].lower()
|
||||||
if t == 'palette':
|
if t == 'palette':
|
||||||
return processPalette(asset)
|
return processPalette(asset)
|
||||||
# elif t == 'image':
|
elif t == 'image':
|
||||||
# return processImage(asset)
|
return processImage(asset)
|
||||||
# elif t == 'tileset':
|
# elif t == 'tileset':
|
||||||
# return processTileset(asset)
|
# return processTileset(asset)
|
||||||
else:
|
else:
|
||||||
|
78
tools/assetstool/processimage.py
Normal file
78
tools/assetstool/processimage.py
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from PIL import Image
|
||||||
|
from processpalette import extractPaletteFromImage, palettes
|
||||||
|
from args import args
|
||||||
|
from assethelpers import getAssetRelativePath
|
||||||
|
|
||||||
|
images = []
|
||||||
|
|
||||||
|
def processImage(asset):
|
||||||
|
type = asset['options'].get('type', 'PALETTIZED').upper()
|
||||||
|
if type == 'PALETTIZED':
|
||||||
|
return processPalettizedImage(asset)
|
||||||
|
elif type == 'ALPHA':
|
||||||
|
return processAlphaImage(asset)
|
||||||
|
else:
|
||||||
|
print(f"Error: Unknown image type {type} for asset {asset['path']}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def processPalettizedImage(asset):
|
||||||
|
assetPath = asset['path']
|
||||||
|
|
||||||
|
image = Image.open(assetPath)
|
||||||
|
imagePalette = extractPaletteFromImage(image)
|
||||||
|
|
||||||
|
# Find palette that contains every color
|
||||||
|
for palette in palettes:
|
||||||
|
if all(color in palette['pixels'] for color in imagePalette):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
print(f"No matching palette found for {assetPath}!")
|
||||||
|
# Find which pixel is missing
|
||||||
|
for color in imagePalette:
|
||||||
|
if color not in palette:
|
||||||
|
print(f"Missing color: {color}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
print(f"Converting image {assetPath} to use palette")
|
||||||
|
|
||||||
|
paletteIndexes = []
|
||||||
|
for pixel in list(image.getdata()):
|
||||||
|
if pixel[3] == 0:
|
||||||
|
pixel = (0, 0, 0, 0)
|
||||||
|
paletteIndex = palette['pixels'].index(pixel)
|
||||||
|
paletteIndexes.append(paletteIndex)
|
||||||
|
|
||||||
|
data = bytearray()
|
||||||
|
data.extend(b"DPI") # Dusk Palettized Image
|
||||||
|
data.extend(image.width.to_bytes(4, 'little')) # Width
|
||||||
|
data.extend(image.height.to_bytes(4, 'little')) # Height
|
||||||
|
data.append(palette['paletteIndex']) # Palette index
|
||||||
|
for paletteIndex in paletteIndexes:
|
||||||
|
if paletteIndex > 255 or paletteIndex < 0:
|
||||||
|
print(f"Error: Palette index {paletteIndex} exceeds 255!")
|
||||||
|
sys.exit(1)
|
||||||
|
data.append(paletteIndex.to_bytes(1, 'little')[0]) # Pixel index
|
||||||
|
|
||||||
|
relative = getAssetRelativePath(assetPath)
|
||||||
|
fileNameWithoutExt = os.path.splitext(os.path.basename(assetPath))[0]
|
||||||
|
outputFileRelative = os.path.join(os.path.dirname(relative), f"{fileNameWithoutExt}.dpi")
|
||||||
|
outputFilePath = os.path.join(args.output_assets, outputFileRelative)
|
||||||
|
os.makedirs(os.path.dirname(outputFilePath), exist_ok=True)
|
||||||
|
with open(outputFilePath, "wb") as f:
|
||||||
|
f.write(data)
|
||||||
|
|
||||||
|
outImage = {
|
||||||
|
"files": [ outputFilePath ],
|
||||||
|
}
|
||||||
|
return outImage
|
||||||
|
|
||||||
|
def processAlphaImage(asset):
|
||||||
|
assetPath = asset['path']
|
||||||
|
print(f"Processing alpha image: {assetPath}")
|
||||||
|
|
||||||
|
outImage = {
|
||||||
|
"files": []
|
||||||
|
}
|
||||||
|
return outImage
|
@@ -13,7 +13,7 @@ def extractPaletteFromImage(image):
|
|||||||
pixels = list(image.getdata())
|
pixels = list(image.getdata())
|
||||||
uniqueColors = []
|
uniqueColors = []
|
||||||
for color in pixels:
|
for color in pixels:
|
||||||
# We treat alpha 0 as rgba(0,0,0,0) for palette purposes
|
# We treat all alpha 0 as rgba(0,0,0,0) for palette purposes
|
||||||
if color[3] == 0:
|
if color[3] == 0:
|
||||||
color = (0, 0, 0, 0)
|
color = (0, 0, 0, 0)
|
||||||
if color not in uniqueColors:
|
if color not in uniqueColors:
|
||||||
|
Reference in New Issue
Block a user