#!/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)