From 31fa4948d509868cb7fe62d3b6665e8c800e3e7f Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Wed, 27 Aug 2025 22:43:38 -0500 Subject: [PATCH] Image generation? --- assets/CMakeLists.txt | 5 +-- assets/first.palette.png | Bin 287 -> 268 bytes assets/test.palette.png | Bin 84 -> 0 bytes src/asset/asset.c | 14 +----- src/engine/engine.c | 2 +- tools/assetstool/processimage.py | 68 ++++++++++++++++++++++++++--- tools/assetstool/processtileset.py | 29 ++++++------ 7 files changed, 80 insertions(+), 38 deletions(-) delete mode 100644 assets/test.palette.png diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 96118a1..9d910c8 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -3,6 +3,5 @@ # This software is released under the MIT License. # https://opensource.org/licenses/MIT -add_asset(test.palette.png) -# add_asset(first.palette.png) -# add_asset(entities.tsx) \ No newline at end of file +add_asset(first.palette.png) +add_asset(entities.tsx) \ No newline at end of file diff --git a/assets/first.palette.png b/assets/first.palette.png index fc473aa8b8e7830c40ccb25a3abef754836764d5..c611a09343f9dfe7d6667e42c41b2521464caac4 100644 GIT binary patch delta 227 zcmV<90383H0*nHXF@MHML_t&-l}*eMbHi{PfZ?ZifkGirCEGeY8~{PmXa`#5ot;THI}g zz3?FHgk~51l{HP{m=Z&+95d}lZslrS4aPE87L%766SNFlE?nop!XI^?;^vL*l-$E` zqPWPaQQGt_&Bke{DO%^Lv41@2y6$%n5%K)>ZGBA&6fnM;ZzijJmgaXu!Jt9mHY?4a d$+B85;0Nf{QBuF?LDm2O002ovPDHLkV1j>7W#<3@ delta 246 zcmVwkECn$~stXRP&NJIsKkdcUr%8HkLd>?JwDu}{X>td^~Y_!K~@6eYV zeJoMdC{HLWl(brl!L1I2Y4z{0%c^)eE5={UA diff --git a/src/asset/asset.c b/src/asset/asset.c index 1a6fe82..4e08f35 100644 --- a/src/asset/asset.c +++ b/src/asset/asset.c @@ -40,18 +40,6 @@ errorret_t assetInit(void) { // 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(); } @@ -98,6 +86,8 @@ void assetLoad( return; } + printf("Loading asset: %s\n", filename); + // Determine length of the file (uncompressed) struct zip_stat st; if(zip_stat(ASSET.zip, filename, 0, &st) != 0) { diff --git a/src/engine/engine.c b/src/engine/engine.c index dcba17a..58ff9ff 100644 --- a/src/engine/engine.c +++ b/src/engine/engine.c @@ -35,7 +35,7 @@ errorret_t engineInit(void) { errorChain(assetInit()); errorChain(displayInit()); - assetLoad("test.palette.dpf", assetLoadCallback, NULL); + assetLoad("first.palette.dpf", assetLoadCallback, NULL); if(ASSET.state == ASSET_STATE_ERROR) errorChain(ASSET.error); sceneTestAdd(); diff --git a/tools/assetstool/processimage.py b/tools/assetstool/processimage.py index 7771b3c..372daa7 100644 --- a/tools/assetstool/processimage.py +++ b/tools/assetstool/processimage.py @@ -2,6 +2,10 @@ import os from args import args from PIL import Image import struct +import sys +from assethelpers import getAssetRelativePath + +PALETTES = [] def extractPaletteFromImage(image): # goes through and finds all unique colors in the image @@ -10,6 +14,9 @@ def extractPaletteFromImage(image): pixels = list(image.getdata()) uniqueColors = [] for color in pixels: + # We treat alpha 0 as rgba(0,0,0,0) for palette purposes + if color[3] == 0: + color = (0, 0, 0, 0) if color not in uniqueColors: uniqueColors.append(color) return uniqueColors @@ -40,21 +47,70 @@ def processPalette(assetPath): outputRelative = os.path.relpath(outputFilePath, args.output_assets) - return { + palette = { "outputFile": outputRelative, "paletteColors": len(pixels), - "files": [ outputFilePath ] + "files": [ outputFilePath ], + "pixels": pixels } + PALETTES.append(palette) + + return palette + def processImage(assetPath): print(f"Processing image: {assetPath}") # Load the image image = Image.open(assetPath) - pixels = extractPaletteFromImage(image) + + # Get the image's palette because we are going to try and find a matching + # palette from the already processed palettes... + imagePalette = extractPaletteFromImage(image) + + # Now find which palette has every single color in this image's palette + paletteIndex = -1 + for i, palette in enumerate(PALETTES): + paletteColors = palette["pixels"] + if all(color in paletteColors for color in imagePalette): + paletteIndex = i + break + + # Did we manage to find a matching palette? + if paletteIndex == -1: + print(f"Error: No matching palette found for image {assetPath}. Please process a suitable palette first.") + sys.exit(1) + + # We found the palette, so now we can convert the image to use that palette + palette = PALETTES[paletteIndex] + indexes = [] + for color in imagePalette: + if color in palette["pixels"]: + index = palette["pixels"].index(color) + indexes.append(index) + else: + print(f"Error: Color {color} in image {assetPath} not found in palette.") + sys.exit(1) + + 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: + # Write header + f.write(b"DPI") # Dusk Palettized Image + f.write(struct.pack("