diff --git a/projects/kissaten_yugure/art/affinity-aki-neutral.png b/projects/kissaten_yugure/art/affinity-aki-neutral.png new file mode 100644 index 0000000..1ecd221 Binary files /dev/null and b/projects/kissaten_yugure/art/affinity-aki-neutral.png differ diff --git a/projects/kissaten_yugure/art/aki-neutral-48b.png b/projects/kissaten_yugure/art/aki-neutral-48b.png new file mode 100644 index 0000000..0858671 Binary files /dev/null and b/projects/kissaten_yugure/art/aki-neutral-48b.png differ diff --git a/projects/kissaten_yugure/art/kissaten-full.aco b/projects/kissaten_yugure/art/kissaten-full.aco new file mode 100644 index 0000000..e755033 Binary files /dev/null and b/projects/kissaten_yugure/art/kissaten-full.aco differ diff --git a/projects/kissaten_yugure/art/kissaten-full.ase b/projects/kissaten_yugure/art/kissaten-full.ase new file mode 100644 index 0000000..d185016 Binary files /dev/null and b/projects/kissaten_yugure/art/kissaten-full.ase differ diff --git a/projects/kissaten_yugure/art/kissaten-full.gpl b/projects/kissaten_yugure/art/kissaten-full.gpl new file mode 100644 index 0000000..243c00c --- /dev/null +++ b/projects/kissaten_yugure/art/kissaten-full.gpl @@ -0,0 +1,20 @@ +GIMP Palette +Name: Kissaten Yugure (full) +Columns: 16 +# + 0 0 0 transparent + 36 36 36 outline + 73 36 36 dark wood +146 73 36 mid wood +182 109 73 light wood +255 182 73 lamp glow +255 219 146 cream +109 73 73 muted wall + 73 36 146 dusk deep +146 73 182 dusk violet +219 109 109 dusk rose +255 146 73 horizon amber +109 36 0 coffee + 73 109 182 coat blue +255 182 146 skin +255 255 219 warm white diff --git a/projects/kissaten_yugure/art/kissaten-full.png b/projects/kissaten_yugure/art/kissaten-full.png new file mode 100644 index 0000000..937b0b6 Binary files /dev/null and b/projects/kissaten_yugure/art/kissaten-full.png differ diff --git a/projects/kissaten_yugure/art/kissaten-portrait.aco b/projects/kissaten_yugure/art/kissaten-portrait.aco new file mode 100644 index 0000000..98e7218 Binary files /dev/null and b/projects/kissaten_yugure/art/kissaten-portrait.aco differ diff --git a/projects/kissaten_yugure/art/kissaten-portrait.ase b/projects/kissaten_yugure/art/kissaten-portrait.ase new file mode 100644 index 0000000..dd52a89 Binary files /dev/null and b/projects/kissaten_yugure/art/kissaten-portrait.ase differ diff --git a/projects/kissaten_yugure/art/kissaten-portrait.gpl b/projects/kissaten_yugure/art/kissaten-portrait.gpl new file mode 100644 index 0000000..df13a9a --- /dev/null +++ b/projects/kissaten_yugure/art/kissaten-portrait.gpl @@ -0,0 +1,15 @@ +GIMP Palette +Name: Kissaten Yugure (portrait) +Columns: 11 +# + 36 36 36 outline + 73 36 36 dark wood +146 73 36 mid wood +182 109 73 light wood +255 182 73 lamp glow +255 219 146 cream +109 73 73 muted wall +109 36 0 coffee + 73 109 182 coat blue +255 182 146 skin +255 255 219 warm white diff --git a/projects/kissaten_yugure/art/kissaten-portrait.png b/projects/kissaten_yugure/art/kissaten-portrait.png new file mode 100644 index 0000000..f61ed29 Binary files /dev/null and b/projects/kissaten_yugure/art/kissaten-portrait.png differ diff --git a/projects/kissaten_yugure/tools/make_palettes.py b/projects/kissaten_yugure/tools/make_palettes.py new file mode 100644 index 0000000..08680c2 --- /dev/null +++ b/projects/kissaten_yugure/tools/make_palettes.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +"""Emit the Kissaten palette in every format the art tools want. + + python3 tools/make_palettes.py + + .gpl GIMP / Inkscape / Krita / Aseprite + .ase Affinity (Photo, Designer, Publisher), Illustrator + .aco Affinity, Photoshop + .act Photoshop indexed-colour tables + .png 16x1 exact + a swatch strip, and a palette reference for generators + +Two sets are written: the full 16 (scene work) and the 11-colour portrait +subset with the sky slots and the transparent index removed. +""" +import struct, os, sys + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from pixtool import PALETTE, write_png + +NAMES = ["transparent", "outline", "dark wood", "mid wood", "light wood", + "lamp glow", "cream", "muted wall", "dusk deep", "dusk violet", + "dusk rose", "horizon amber", "coffee", "coat blue", "skin", + "warm white"] +PORTRAIT_IDX = [1, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15] +OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "art") + + +def gpl(path, cols, names, title): + L = [f"GIMP Palette", f"Name: {title}", f"Columns: {len(cols)}", "#"] + for c, n in zip(cols, names): + L.append(f"{c[0]:3d} {c[1]:3d} {c[2]:3d}\t{n}") + open(path, "w").write("\n".join(L) + "\n") + + +def ase(path, cols, names): + blocks = b"" + for c, n in zip(cols, names): + nm = n.encode("utf-16-be") + b"\x00\x00" + body = (struct.pack(">H", len(n) + 1) + nm + b"RGB " + + struct.pack(">fff", c[0] / 255, c[1] / 255, c[2] / 255) + + struct.pack(">H", 2)) # 2 = normal colour + blocks += struct.pack(">HI", 0x0001, len(body)) + body + open(path, "wb").write(b"ASEF" + struct.pack(">HHI", 1, 0, len(cols)) + blocks) + + +def aco(path, cols, names): + # v1 then v2 concatenated — v1 for old readers, v2 carries the names + v1 = struct.pack(">HH", 1, len(cols)) + for c in cols: + v1 += struct.pack(">HHHHH", 0, c[0] * 257, c[1] * 257, c[2] * 257, 0) + v2 = struct.pack(">HH", 2, len(cols)) + for c, n in zip(cols, names): + v2 += struct.pack(">HHHHH", 0, c[0] * 257, c[1] * 257, c[2] * 257, 0) + v2 += struct.pack(">I", len(n) + 1) + n.encode("utf-16-be") + b"\x00\x00" + open(path, "wb").write(v1 + v2) + + +def act(path, cols): + d = bytearray() + for c in cols: + d += bytes(c) + d += bytes(768 - len(d)) + open(path, "wb").write(bytes(d)) + + +def swatches(path, cols, sw=32, h=64): + write_png(path, [[c for c in cols for _ in range(sw)]] * h) + + +def emit(stem, idx, title): + cols = [PALETTE[i] for i in idx] + names = [NAMES[i] for i in idx] + p = lambda ext: os.path.normpath(os.path.join(OUT, f"{stem}.{ext}")) + gpl(p("gpl"), cols, names, title) + ase(p("ase"), cols, names) + aco(p("aco"), cols, names) + act(p("act"), cols) + swatches(p("png"), cols) + print(f"{stem}: {len(cols)} colours -> .gpl .ase .aco .act .png") + + +if __name__ == "__main__": + emit("kissaten-full", list(range(16)), "Kissaten Yugure (full)") + emit("kissaten-portrait", PORTRAIT_IDX, "Kissaten Yugure (portrait)") + # exact 1px-per-entry image, for generators that take a palette image + write_png(os.path.normpath(os.path.join(OUT, "palette.png")), [list(PALETTE)]) + print("palette.png: 16x1 exact")