joeylib2/scripts/lib/keysCells.py

73 lines
2.2 KiB
Python

#!/usr/bin/env python3
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
# See LICENSE.md for license information.
# SPDX-License-Identifier: MIT
"""keysCells.py - read which of KEYS's named-key cells are lit off a screenshot.
KEYS (examples/keys) draws a cell for each named key, lit (colour 2, green)
while jlKeyDown says it is down and dark grey (colour 1) otherwise. This
reads the cells of its fourth row that a port gives a second physical key
for -- Return, Ctrl, Alt, Up, Down, Left, and Right -- at the middle of
each, and prints one digit a cell, in that order: 1 lit, 0 not, ? neither
colour.
keysCells.py PNG [--at X,Y] [--scale S]
--at: where the stage's top left is in the screenshot (default 0,0).
--scale: screen pixels a stage pixel (default 1).
"""
import sys
from PIL import Image
# examples/keys: CELL_W x CELL_H cells GAP apart from (MARGIN_X, MARGIN_Y),
# the named keys in row 4 at these columns.
CELL_W = 28
CELL_H = 26
GAP = 4
MARGIN_X = 2
MARGIN_Y = 2
ROW = 4
COLUMNS = (2, 3, 4, 5, 6, 7, 8) # Return, Ctrl, Alt, Up, Down, Left, Right
# KEYS's colours 1 and 2 (12-bit $333 and $0F0, each channel widened x17).
UNLIT = (0x33, 0x33, 0x33)
LIT = (0x00, 0xFF, 0x00)
# A 15- or 16-bit screen is off by at most 8 a channel.
MAX_DIST = 3 * 9 ** 2
def near(got, want):
return sum((g - w) ** 2 for g, w in zip(got, want)) <= MAX_DIST
def main(argv):
args = argv[1:]
at = (0, 0)
scale = 1
png = None
while args:
arg = args.pop(0)
if arg == "--at":
at = tuple(int(v) for v in args.pop(0).split(","))
elif arg == "--scale":
scale = int(args.pop(0))
else:
png = arg
if png is None:
print(__doc__.strip(), file=sys.stderr)
return 2
image = Image.open(png).convert("RGB")
y = MARGIN_Y + ROW * (CELL_H + GAP) + CELL_H // 2
digits = []
for column in COLUMNS:
x = MARGIN_X + column * (CELL_W + GAP) + CELL_W // 2
pixel = image.getpixel((at[0] + x * scale, at[1] + y * scale))
digits.append("1" if near(pixel, LIT) else ("0" if near(pixel, UNLIT) else "?"))
print("".join(digits))
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv))