First public commit.
This commit is contained in:
parent
2a48f52979
commit
4bac9d83ed
288 changed files with 18417 additions and 1076 deletions
69
lenser/coco/palette.py
Normal file
69
lenser/coco/palette.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"""TRS-80 Color Computer MC6847 VDG palette + pixel packing.
|
||||
|
||||
PMODE 4 (256x192) is 2-colour: black + the foreground of the selected colour set
|
||||
(CSS=0 green, CSS=1 "buff" ~ off-white). We use CSS=1 (buff on black) for clean
|
||||
monochrome, like Apple HGR mono.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
|
||||
from ..palette import srgb_to_lab
|
||||
|
||||
# Approximate sRGB for the MC6847 colours.
|
||||
BLACK = (0, 0, 0)
|
||||
BUFF = (255, 255, 255)
|
||||
GREEN = (38, 194, 64)
|
||||
YELLOW = (255, 240, 112)
|
||||
BLUE = (40, 62, 211)
|
||||
RED = (180, 38, 40)
|
||||
CYAN = (52, 198, 160)
|
||||
MAGENTA = (200, 70, 180)
|
||||
ORANGE = (224, 116, 36)
|
||||
|
||||
# PMODE 4 monochrome (CSS=1): index 0 = black, 1 = buff.
|
||||
MONO = np.array([BLACK, BUFF], dtype=np.float64)
|
||||
|
||||
# PMODE 3 (CG6) 4-colour sets, selected by the CSS bit. The 2-bit pixel value
|
||||
# 0..3 indexes the set. VDG byte ($FF22) high nibble = E (A/G,GM2,GM1=1, GM0=0).
|
||||
PMODE3_SETS = {
|
||||
0xE0: np.array([GREEN, YELLOW, BLUE, RED], dtype=np.float64), # CSS=0
|
||||
0xE8: np.array([BUFF, CYAN, MAGENTA, ORANGE], dtype=np.float64), # CSS=1
|
||||
}
|
||||
|
||||
|
||||
def mono_lab() -> np.ndarray:
|
||||
return srgb_to_lab(MONO)
|
||||
|
||||
|
||||
def pack_pmode3(val: np.ndarray) -> bytes:
|
||||
"""Pack a (192,128) 0..3 array into 6144 bytes, 4 pixels/byte (2bpp),
|
||||
leftmost pixel in the high bits."""
|
||||
h, w = val.shape
|
||||
out = bytearray(w // 4 * h)
|
||||
k = 0
|
||||
for y in range(h):
|
||||
row = val[y]
|
||||
for x in range(0, w, 4):
|
||||
out[k] = ((row[x] & 3) << 6) | ((row[x + 1] & 3) << 4) | \
|
||||
((row[x + 2] & 3) << 2) | (row[x + 3] & 3)
|
||||
k += 1
|
||||
return bytes(out)
|
||||
|
||||
|
||||
def pack_pmode4(idx: np.ndarray) -> bytes:
|
||||
"""Pack a (192,256) 0/1 array into 6144 bytes, 8 pixels/byte, bit7 leftmost,
|
||||
1 = foreground (the VDG reads this straight from video RAM)."""
|
||||
h, w = idx.shape
|
||||
out = bytearray(w // 8 * h)
|
||||
k = 0
|
||||
for y in range(h):
|
||||
row = idx[y]
|
||||
for x in range(0, w, 8):
|
||||
b = 0
|
||||
for i in range(8):
|
||||
b = (b << 1) | (1 if row[x + i] else 0)
|
||||
out[k] = b
|
||||
k += 1
|
||||
return bytes(out)
|
||||
Loading…
Add table
Add a link
Reference in a new issue