103 lines
4.5 KiB
Python
103 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""led3number.c 移位逻辑模拟器 — 用于精确理解/验证 32x16 点阵数字布局"""
|
|
import re, sys
|
|
|
|
SRC = "/root/.openclaw/media/inbound/led3number---69efe51a-567a-4354-a1b8-6c796c184183.txt"
|
|
text = open(SRC, encoding="utf-8", errors="replace").read()
|
|
|
|
# ---------- 1. 解析字库 Code_Number_16_12[17][32] ----------
|
|
m = re.search(r"Code_Number_16_12\[17\]\[32\]\s*=\s*\{(.*?)\n\};", text, re.S)
|
|
assert m, "字库未找到"
|
|
body = m.group(1)
|
|
# 按 { ... }, //n 拆成 17 个字符
|
|
entries = re.findall(r"\{([^{}]*)\}", body)
|
|
assert len(entries) >= 11, f"字库条目数 {len(entries)} < 11"
|
|
fonts = []
|
|
for e in entries:
|
|
vals = [int(x, 16) for x in re.findall(r"0[xX][0-9A-Fa-f]+", e)]
|
|
assert len(vals) == 32, f"条目字节数 {len(vals)} != 32"
|
|
fonts.append(vals)
|
|
print(f"[字库] 解析 OK: 17 个字符 x 32 字节")
|
|
|
|
# ---------- 2. 模拟填充 + 移位(完全照抄 C 逻辑, uint8 语义) ----------
|
|
def simulate(chars_idx, new_layout=False):
|
|
"""chars_idx: 4 个字符索引, 0-9=数字, 16=空格(Code_Number_16_12[10]=空格索引10, 但调用处用 0x20 判断)"""
|
|
code12 = [[0]*16 for _ in range(8)] # 8 槽 x 16 行, uint8
|
|
for roll in range(4):
|
|
cc = chars_idx[roll]
|
|
for i in range(16):
|
|
if cc == 0x20 or cc == 16: # 空格
|
|
code12[roll*2][i] = fonts[10][i*2]
|
|
code12[roll*2+1][i] = fonts[10][i*2+1]
|
|
else:
|
|
code12[roll*2][i] = fonts[cc][i*2]
|
|
code12[roll*2+1][i] = (fonts[cc][i*2+1] << 6) & 0xFF
|
|
if not new_layout:
|
|
# ---- 原移位拼接(TODO 所在处, 原样模拟) ----
|
|
for i in range(16):
|
|
m1 = code12[5][i]
|
|
code12[4][i] = ((code12[4][i] << 1) | (m1 >> 7)) & 0xFF
|
|
code12[5][i] = (code12[5][i] << 1) & 0xFF
|
|
|
|
m1 = code12[4][i]
|
|
code12[3][i] = (code12[3][i] | (m1 >> 4)) & 0xFF
|
|
|
|
m1 = code12[4][i]
|
|
m2 = code12[5][i]
|
|
code12[4][i] = ((m1 << 4) | (m2 >> 4)) & 0xFF
|
|
|
|
m1 = code12[6][i]
|
|
code12[4][i] = (code12[4][i] | (m1 >> 6)) & 0xFF
|
|
m1 = code12[6][i]
|
|
code12[5][i] = ((m1 << 2) | (code12[7][i] >> 6)) & 0xFF
|
|
else:
|
|
# ---- 新布局: 1空 | [2空 7数字 1空]x3 | 1空 = 32列 ----
|
|
# 数字1(槽2,3) 区域内列2-8 → 全局列3-9
|
|
# 数字2(槽4,5) 区域内列2-8 → 全局列13-19
|
|
# 数字3(槽6,7) 区域内列2-8 → 全局列23-29
|
|
for i in range(16):
|
|
s2 = code12[2][i]; s3 = code12[3][i]
|
|
s4 = code12[4][i]; s5 = code12[5][i]
|
|
s6 = code12[6][i]; s7 = code12[7][i]
|
|
code12[2][i] = (s2 >> 1) & 0x1F # 数字1: 列3-7
|
|
code12[3][i] = ((s2 & 0x01) << 7) | ((s3 >> 1) & 0x40) \
|
|
| ((s4 >> 3) & 0x07) # 数字1列8-9 | 数字2列13-15
|
|
code12[4][i] = ((s4 & 0x07) << 5) | ((s5 & 0x80) >> 3) \
|
|
| ((s6 >> 5) & 0x01) # 数字2列16-19 | 数字3列23
|
|
code12[5][i] = ((s6 & 0x1F) << 3) | ((s7 & 0x80) >> 5) # 数字3列24-29
|
|
# memcpy 输出: 槽 2,3,4,5 → 每行 4 字节 = 32 列
|
|
out = [code12[s][i] for i in range(16) for s in (2,3,4,5)]
|
|
return out
|
|
|
|
def render(out, title):
|
|
print(f"\n=== {title} ===")
|
|
print("col: " + "".join(str(c % 10) for c in range(32)))
|
|
for row in range(16):
|
|
line = ""
|
|
for c in range(32):
|
|
byte = out[row*4 + c//8]
|
|
bit = (byte >> (7 - (c % 8))) & 1 # MSB first: bit7=列左
|
|
line += "#" if bit else "."
|
|
print(f"{row:2d} {line}")
|
|
# 每列统计
|
|
colsum = [0]*32
|
|
for row in range(16):
|
|
for c in range(32):
|
|
byte = out[row*4 + c//8]
|
|
colsum[c] += (byte >> (7 - (c % 8))) & 1
|
|
print("col#: " + "".join(str(colsum[c]) for c in range(32)))
|
|
# 亮列区间
|
|
lit = [c for c in range(32) if colsum[c] > 0]
|
|
print("亮列:", lit)
|
|
|
|
# ---------- 3. 测试几种字符组合 ----------
|
|
import itertools
|
|
# 原布局
|
|
for name, chars in [("OLD 123+0", [1,2,3,0]), ("OLD 456+7", [4,5,6,7]), ("OLD 888+8", [8,8,8,8])]:
|
|
render(simulate(chars), name)
|
|
# 新布局
|
|
for name, chars in [("NEW 123+0", [1,2,3,0]), ("NEW 456+7", [4,5,6,7]), ("NEW 888+8", [8,8,8,8]),
|
|
("NEW 000+0", [0,0,0,0]), ("NEW 999+9", [9,9,9,9]), ("NEW 111+1", [1,1,1,1])]:
|
|
render(simulate(chars, new_layout=True), name)
|