# 首关 ROM 重建 · v2.1.1

城市模式使用独立的 `rom-city-core.js`，从 1280 像素的改编选段改为 ROM 中的 28 屏、7168×224 地图。跑兵、枪手、狗、车辆残骸、飞行胶囊和五种弹体从运行显存与 OAM 提取，以 CSS 硬边渐变绘制。v2.1.1 按用户要求恢复 FC/NES 玩家外观与尺寸；已提取的 SFC 玩家素材仍保留在资产库。背景采用蓝、赭两套 FC 色组；游戏运行时没有 Canvas、SVG 或位图。

本次修复金属台阶落脚、柱体侧面与底面阻挡、攀爬至顶、小 Boss 击破清场。新增 SA-1 运行反汇编与 111 帧台阶坐标对照；地址、复现步骤和证据见 [逻辑逆向记录](ROM_LOGIC.md)。

**这是可玩的首关重建进度版，不是完整或逐帧等价的 Contra III 移植。** 工厂与巢穴仍使用 v2.0 的改编规则。下方明确区分已验证和待完成的部分。

## 已与运行记录核对

- 基线为本地修改版 SA-1 ROM，SHA-256 `44ebb9a450b5b77341fc9130ab45767a13212c242350aad450a4526f8a8d8017`，不是干净美版 ROM。不能把该文件的测量直接宣称为所有发行版本的行为。
- 首关 BG1 定义由文件偏移 `0x53064` 的 8192 字节和新确认的 `0x54DBC` 的 5376 字节组成；13568 字节全部匹配运行 RAM `0x5000`。之前只读前一块会误画后半关。
- `0x55871` 布局每屏包含 8×8 个 32 像素块；地址低 14 位是定义偏移，高两位是水平、垂直翻转。28 屏布局完整导入。
- 碰撞分类来自 ROM `$00:CC77–CCEF` 与关卡阈值 `$C8–DE`。六个滚动位置的 **5040 个碰撞条目**全部匹配运行 RAM。静态背景中有 72 个条目与已被破坏的运行场景不同，差异原样保留在参考文件，没有丢弃后只报告匹配项。
- 横移为 `360/256` 像素/帧；初始跳速 `-6`，重力 `0.25` 像素/帧²。130 帧自然输入的横坐标和物理脚底坐标与 ROM **完全相同**。跳跃图片本身的脚部偏移不混入物理坐标。
- M/S/C/H/L 定点持续射击的开火帧已逐项比较。前 40 帧：M 每 3 帧；S 为 0、4、28、32；C 为 0、5、10；H 为 0、4、8、12、16、24、28、32；L 为 0、39。C 的下一轮在第 50 帧，L 在第 78 帧再次开火。
- S 使用两组五发；两组各残留几发时，不允许把空余槽拼成第三组。五个初始 16.16 速度向量逐项匹配。
- 初始双槽为 M/M；B 沿用已测得的 512 帧，复活保护 96 帧。保留默认 30 命和自由选关。
- 原版 75 条关卡事件均已读出；当前接入其中的飞行补给、车辆残骸、枪手、狗、刷兵开关与两道墙体。未接入的事件也保留在数据中。

## 已重建但尚非逐帧等价

左右跑兵采用测得的速度，面向始终跟随运动；出现间隔、枪手射击节奏仍是重建逻辑。飞行胶囊的道具、方向和触发位置来自 ROM，摆动轨迹尚未逐帧对齐。

两道墙体锁住镜头，红色弱点可被击破，击破后恢复通路、清除附近敌兵与敌弹。即时清场按用户要求适配，不能等同原版多段破坏时序；墙体血量、炮口节奏和破坏动画未完成原版逐帧校准。

关底龟兽采用原生 160×168 美术，弱点位于红色心脏；从甲壳释放可击破的空中与地面敌人。外形来自此前取得的 SNES Maps 提取图，尚未在本轮运行记录中提取；血量、敌人造型与攻击周期仍需校准。该行为方向参考 [insannescorp55 的原始 Boss 攻略](https://gamefaqs.gamespot.com/snes/563543-contra-iii-the-alien-wars/faqs/20520)，不能称为 ROM 参数移植。

## 仍需完成

- 可驾驶坦克、轰炸机点燃街道、榴弹坦克中 Boss、后半段火焰与碎石机关。
- 后段动态背景切换、部分可破坏建筑与精确斜坡轮廓。台阶和柱面已接入；攀爬速度、姿势与特殊斜坡仍需原版校准。
- F 火焰的连续链条、H 追踪转向、C 爆炸受击与 L 全方向细节的完整核对。
- Boss 完整动画和攻击参数；工厂与巢穴的同规格重建。
- 完整原版音乐、双人、俯视关卡。

这些项目不会因为普通按键通关测试通过而被视为已完成。

## 复现与测试

`tools/snes/probe.c` 使用 Snes9x libretro 1.63 核心，只读取 ROM。`CONTRA_LOAD_STATE` 加载本地状态，`CONTRA_INPUT` 指向 `开始帧,结束帧,按键位掩码` CSV；`CONTRA_FRAMES` 控制帧数，`CONTRA_DUMP_EVERY` 控制快照间隔，`CONTRA_TRACE_RAM` 输出每帧前 8 KiB 的 BW-RAM。输出均放在私有 `work/`。

`CONTRA_GUN` 和 `CONTRA_TIMER_HOLD` 是明确标记的实验干预。移动对照没有 RAM 干预；射击对照只指定武器槽。后段美术探索使用过固定保护计时器，不能当作正常通关证据。实验曾在刷怪槽未释放时停留于页切换循环；清掉对应敌人后已继续越过两道墙，不能据此认定原版游戏存在相同问题。

```powershell
node tools/snes/build-city.cjs ROM_PATH SNAPSHOT_780 assets
node tools/snes/build-actors.cjs PRIVATE_WORK_DIR assets
node tools/snes/city-reference.cjs PRIVATE_WORK_DIR ROM_PATH tests/fixtures/city-rom-reference.json
node --test tests/*.test.cjs
node tools/build-static.cjs
```

运行时不需要 ROM、模拟器、C、Python 或第三方渲染库。编译资产用 Node.js、Sharp 和 SNES 解码工具。开发参考包括 [SNESTilesKitten](https://github.com/Skarsnik/SNESTilesKitten)、[SA1-Root](https://github.com/VitorVilela7/SA1-Root/blob/master/Contra-III/README.md) 和 [Soig 的原始 RAM/武器记录](https://tasvideos.org/6515S)。

v2.1.1 共 260 项自动测试通过，包含 30 个种子的完整首关按键通关、180,000 帧随机输入和独立 ROM 台阶对照。浏览器三关各 10 次通关通过，600 帧回放 57.8 FPS、渲染耗时 P95 0.50 ms、最多 167 个 DOM 节点，0 位图请求。这些性能结果属于本机测量。

完整 ROM、模拟器 DLL、RAM、VRAM、存档快照不进入公开仓库或部署；只提交转换后用于本项目的资产和小型参考数据。
