60 lines
2.4 KiB
Python
60 lines
2.4 KiB
Python
"""Amstrad CPC (Gate Array) colour palette.
|
|
|
|
The CPC has a fixed palette of 27 colours (3 levels -- 0x00, 0x60, 0xFF -- of
|
|
R, G and B). The Gate Array selects them by a 5-bit "hardware ink" number 0-31;
|
|
those 32 numbers map onto the 27 colours (a few duplicates). RGB values and the
|
|
hardware-ink ordering are taken verbatim from MAME's ``amstrad_palette[32]`` so
|
|
the encoder matches exactly what the emulator renders.
|
|
|
|
A pen (the value stored per pixel: 0-15 in mode 0, 0-3 in mode 1, 0-1 in mode 2)
|
|
is assigned an ink via the Gate Array palette; the .sna stores those 17 ink
|
|
numbers (16 pens + border). We therefore index colours by HARDWARE INK NUMBER,
|
|
so ``HW_INK[k]`` is both this palette's RGB and the byte written to the snapshot.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import numpy as np
|
|
|
|
from ..palette import srgb_to_lab
|
|
|
|
# amstrad_palette[32] from MAME (src/mame/amstrad/amstrad_m.cpp), indexed by the
|
|
# Gate Array hardware ink number.
|
|
HW_INK = np.array([
|
|
(96, 96, 96), (96, 96, 96), (0, 255, 96), (255, 255, 96),
|
|
(0, 0, 96), (255, 0, 96), (0, 96, 96), (255, 96, 96),
|
|
(255, 0, 96), (255, 255, 96), (255, 255, 0), (255, 255, 255),
|
|
(255, 0, 0), (255, 0, 255), (255, 96, 0), (255, 96, 255),
|
|
(0, 0, 96), (0, 255, 96), (0, 255, 0), (0, 255, 255),
|
|
(0, 0, 0), (0, 0, 255), (0, 96, 0), (0, 96, 255),
|
|
(96, 0, 96), (96, 255, 96), (96, 255, 0), (96, 255, 255),
|
|
(96, 0, 0), (96, 0, 255), (96, 96, 0), (96, 96, 255),
|
|
], dtype=np.float64)
|
|
|
|
# The 27 unique colours, each as the FIRST hardware ink number that produces it
|
|
# (so encoders work with a clean 27-entry palette, and INK[i] gives the snapshot
|
|
# byte for unique colour i).
|
|
INK = []
|
|
_seen = {}
|
|
for _k, _rgb in enumerate(map(tuple, HW_INK.astype(int))):
|
|
if _rgb not in _seen:
|
|
_seen[_rgb] = _k
|
|
INK.append(_k)
|
|
INK = np.array(INK, dtype=np.int64) # 27 hardware ink numbers
|
|
PALETTE = HW_INK[INK] # 27 unique RGB colours
|
|
|
|
# Neutral grey ramp (for the monochrome mode): black, grey, bright white.
|
|
GREYS = [i for i, (r, g, b) in enumerate(map(tuple, PALETTE.astype(int)))
|
|
if r == g == b] # indices into PALETTE
|
|
|
|
|
|
def get_palette() -> np.ndarray:
|
|
return PALETTE
|
|
|
|
|
|
def palette_lab() -> np.ndarray:
|
|
return srgb_to_lab(PALETTE)
|
|
|
|
|
|
def ink_byte(unique_index: int) -> int:
|
|
"""Hardware ink number (snapshot byte) for a unique-palette colour index."""
|
|
return int(INK[unique_index])
|