73 lines
2.2 KiB
Python
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))
|