"""Sinclair ZX Spectrum colour palette. The ULA has 8 base colours, each in a normal and a BRIGHT version (component value 0xD7 normal, 0xFF bright; black is the same in both). Crucially the BRIGHT bit is per 8x8 *cell*, shared by that cell's ink and paper -- so a cell's two colours must both be normal or both be bright (they can't mix). We model this as a 16-entry palette: indices 0-7 = normal, 8-15 = bright, where index & 7 is the ink/paper colour number and index >> 3 is the BRIGHT bit. """ from __future__ import annotations import numpy as np from ..palette import srgb_to_lab _N = 0xD7 # normal-brightness component _B = 0xFF # bright component def _ramp(v): # colour order matches the Spectrum's INK/PAPER numbering 0..7 return [ (0, 0, 0), # 0 black (0, 0, v), # 1 blue (v, 0, 0), # 2 red (v, 0, v), # 3 magenta (0, v, 0), # 4 green (0, v, v), # 5 cyan (v, v, 0), # 6 yellow (v, v, v), # 7 white ] SPECTRUM = np.array(_ramp(_N) + _ramp(_B), dtype=np.float64) # Cell colour pairs must come from one brightness group (shared BRIGHT bit). NORMAL_GROUP = list(range(0, 8)) BRIGHT_GROUP = list(range(8, 16)) def get_palette() -> np.ndarray: return SPECTRUM def palette_lab() -> np.ndarray: return srgb_to_lab(SPECTRUM)