refactor(HDMI-Tool): 划分 src/assets/release 三区目录, 补齐人读/AI 读双文档与发布流水线

This commit is contained in:
2026-09-10 23:44:56 +08:00
parent 0977b275ee
commit a1f6fdd34a
35 changed files with 517 additions and 81 deletions
+105
View File
@@ -0,0 +1,105 @@
# AGENTS.md — HDMI-Tool 工程档案(供 AI/Agent 使用)
> **本文档面向 AI/Agent**,是人类文档 [README.md](README.md) 的姊妹篇,两者不重叠:
> README 回答"这是什么、怎么用";本文回答"代码怎么组织、怎么构建发布、改动时哪些约束不能破坏"。
> 任何 Agent 在修改本目录代码前应先读完本文。
## 1. 项目定位
仓库 `LT8619C_Debug_Tools` 是 LT8619CHDMI→RGB888)→ DLPC3421 投影转接板的**调试上位机工具集**,
上游主仓库(固件)为 `hulk/LT8619C_DLPC3421_HDMI`(同 Gitea 实例 `gitea.hulk.wang`)。
本工具工作在 HDMI **源端**(PC 显卡侧),与固件侧寄存器调试(I2C-Inject 工具)配合。
寄存器语义判读基线(0x606E 位交换 / 0x606D 整组顺序)在上游仓库 `doc/architecture/`,不在本仓库。
## 2. 目录契约(重要)
```
HDMI-Tool/
├── src/ 源代码区 —— 只有这里可以手改(logos/ 改图标源后重跑 make_ico.py
├── assets/ 生成资产区 —— gen_*.py 的产物(PNG 图案),可随时再生成,改动需提交
├── release/ 产物区 —— 机器生成,禁止手改:HDMI-Tool.exe(入库)、
│ pattern_slots.jsonexe 运行配置,入库)、*.zipgitignore,只上传 Release
├── README.md 人类文档
└── AGENTS.md 本文
```
划分原则:**"人写的"在 src/"生成的"按去向分 assets/(随包分发)与 release/(直接交付)**。
新文件必须落对区域;不要在 src/ 外新建源码,不要手改 assets/ 下的 PNG(改生成脚本再跑)。
### 文件角色速查
| 文件 | 角色 |
|---|---|
| `src/hdmi_gui.py` | 单文件主程序:GUI(tkinter) + 命令行,约 1500 行,纯标准库 |
| `src/build_exe.py` | PyInstaller 打包 → `release/HDMI-Tool.exe`onefile/noconsole,内嵌图标) |
| `src/package_release.py` | exe+图案+说明 → `release/HDMI-Tool-v<ver>-win64.zip`(校验栏位引用完整性) |
| `src/publish_gitea.py` | 建/复用 Gitea Release 并上传 ziptag 默认取 zip 文件名) |
| `src/hdmi_source.ps1/.bat` | 独立 PowerShell 命令行工具(自包含,与 GUI 无代码共享) |
| `src/gen_bw_patterns.py` | 生成 `assets/bw_*.png` ×5640x360 黑白,需 Pillow |
| `src/gen_solid_colors.py` | 生成 `assets/solid_*.png` ×10800x600 纯色,需 Pillow |
| `src/la_wave_analyzer*.py` | 逻辑分析仪 CSV 波形判读(2/3 通道,40MHz 像素时钟假设) |
| `src/logos/make_ico.py` | svg/png → ico(写在其自身目录) |
| `release/pattern_slots.json` | 预置栏位:西门子星/波带片/综合测试卡,area=640x360 |
## 3. 代码不变量(改 hdmi_gui.py 必须维持)
1. **纯标准库**hdmi_gui.py 只准 import 标准库(ctypes/winreg/tkinter/…)。Pillow 是
*可选*加速(仅扩展自定义图片格式 PNG/GIF 之外的 JPG/BMP/WebP),缺失时必须照常工作。
2. **BASE_DIR 语义**frozenPyInstaller onefile)时 `BASE_DIR=exe 所在目录``sys.executable`),
源码运行时 `=hdmi_gui.py 所在目录``__file__`)。所有用户数据(pattern_slots.json、
自定义图片)都写/读自 BASE_DIR **平铺**存放,不建子目录。
3. **自定义栏位 `file` 字段是裸文件名**:加载时 `os.path.join(BASE_DIR, file)` 解析,
因此 pattern_slots.json 引用的图片必须与 exe 同目录 —— package_release.py 正是按此平铺打包。
4. **exe 自包含**:图标经 `--add-data` 内嵌(运行时从 `_MEIPASS` 读);内置五种图案
(红/绿/蓝/棋盘格/网格线)由程序绘制,运行时**不依赖** assets/solid/bw PNG 只服务自定义栏位。
5. **DPI 感知**:进程启动即 `SetProcessDpiAwareness(2)`,图案窗口按物理像素定位,勿移除。
6. **启动强制扩展拓扑**`SetDisplayConfig(SDC_TOPOLOGY_EXTEND|SDC_APPLY)`,静默容错
(失败不阻断启动)。动机:LT8619C 热插拔后 Windows 可能停留在"仅电脑屏幕"。
7. **分辨率切换是临时的**:走 `CHANGEDISPLAYSETTINGS`(不写注册表),"恢复"用会话开始时快照。
8. **EDID 来源是注册表**`HKLM\SYSTEM\CurrentControlSet\Enum\DISPLAY\...\Device Parameters\EDID`),
不是 WMI/DDCexe 的 noconsole 版无 stdout`--dump/--edid-fields` 只在源码/控制台版可用。
## 4. 领域语义(测试值都有含义,勿"顺手改")
- 纯色值 55/AA/FF55(01010101) 与 AA(10101010) 互为字节镜像对(检出位序颠倒/位交换),
FF(11111111) 全高基准;R/G/B 三行对应 RGB888 三字节组(R=D[23:16]/G=D[15:8]/B=D[7:0])。
- 800x600@60demo 板 shadow EDID 首选时序(solid 系列分辨率与之一致)。
- 640x360:测试卡区域默认值(16:9 半分辨率,点对点检查用);full=铺满所选屏。
- bw 系列图案各自目的见 `src/gen_bw_patterns.py` 顶部清单注释。
## 5. 构建 / 发布流水线(全部在 src/ 下执行)
```powershell
python gen_bw_patterns.py ; python gen_solid_colors.py # 仅当改了图案生成逻辑
python build_exe.py # → ../release/HDMI-Tool.exe(缺 PyInstaller 会自动 pip install
python build_exe.py --debug # 附加带控制台的 HDMI-Tool-console.exe(调试 --dump 用)
python package_release.py <版本> # → ../release/HDMI-Tool-v<版本>-win64.zip
python publish_gitea.py HDMI-Tool-v<版本>-win64.zip --replace # 上传(需 GITEA_TOKEN 环境变量或 --token)
```
发布约定:
- tag/release 命名 `HDMI-Tool-vX.Y.Z`zip 命名 `HDMI-Tool-vX.Y.Z-win64.zip`publish_gitea.py
依赖此命名从文件名推 tag);
- **exe 与 pattern_slots.json 改动跟随源码提交入库;zip 永不入库**(.gitignore 已挡);
- publish_gitea.py 幂等:release 已存在则复用,同名资产默认跳过,`--replace` 删旧重传;
- Gitea 实例 `gitea.hulk.wang`API 走 https(443)git 走 ssh(1234)——从 origin 远程自动解析;
自签证书报 SSL 错时加 `--insecure`
## 6. 已知坑(历史踩过,勿重蹈)
- onefile 运行时 `__file__` 指向临时解压目录 `_MEIPASS`,定位 exe 必须用 `sys.executable`(§3.2);
- 重新打包前旧 exe 可能被残留进程占用 → build_exe.py 会 taskkill 同名进程,手改打包脚本时保留;
- 打包后本机图标缓存不刷新:`ie4uinit -show`,不是产物问题;
- 改图标流程:改 svg → `make_ico.py` 生成 ico → 重新打包(ico 同时是文件图标与运行时窗口图标);
- GUI 与 hdmi_source.ps1 各自独立实现显示器枚举,行为可能微差(GUI 与 `-List` 序号一致,
但与"设置"面板序号无保证);多屏操作前先确认序号;
- `pattern_slots.json` 兼容两种格式:新 `{area, slots[]}`,旧纯数组(无 area)——load_slots 已兼容,
但写出只应写新格式。
## 7. 验证清单(改完代码后)
1. `python hdmi_gui.py --seconds 5` —— GUI 冒烟(自动开关);
2. `python hdmi_gui.py --test-pattern Checker --area 800x600 --seconds 3` —— 投图链路;
3. `python hdmi_gui.py --dump` —— EDID 解算不抛异常;
4. `python build_exe.py` → 双击 release/HDMI-Tool.exe 确认图标/启动/投图;
5. `python package_release.py <版本>` —— 不报"引用图片缺失"即栏位完整性 OK。