n0isy/fire-and-forget-2-recomp

GitHub: n0isy/fire-and-forget-2-recomp

对 1990 年 DOS 赛车游戏《Fire & Forget II》的逐函数现代化重构,采用 C11+SDL2 实现,支持原生和浏览器运行并附带了字节级可验证的关卡脚本工具链。

Stars: 1 | Forks: 0

# Fire & Forget II — Recomp 对 **Fire & Forget II: The Death Convoy** (Titus Interactive,1990,DOS/EGA)的一次忠实现代化重构(“重新编译”),采用可移植的 **C11 + SDL2** 编写,支持原生运行,并可通过 **WebAssembly** 在浏览器中运行 —— 包含移动端的触摸控制。 该引擎是通过阅读反汇编/反编译的原始 DOS 可执行文件, 并逐个函数进行转写来重构的 —— 而*不是*通过视频来近似还原游戏玩法。 每一个重构的子系统都在运行于 QEMU + GDB 下的真实游戏中进行了验证: **尚未移植:**声音(AdLib / PC speaker)—— 这是唯一缺失的子系统。 ## 你需要原始游戏图像 重构的引擎**及其所有游戏逻辑数据**(关卡脚本、敌人 表、调色板、sprite 合成器程序、LUT、文本……)均以可读的源码形式提供, 因此你不再需要原始可执行文件的 DGROUP 数据块来构建或运行 —— 本次构建是 自包含的(参见下文的*重构数据与工具*)。 **未**重构的是原始**图像**。要运行游戏,你必须拥有 Fire & Forget II,并从你自己的副本中提取其画面、sprite 和 HUD 字体: ``` scripts/extract_assets.sh /path/to/your/FF2 # needs FF2EGA.EXE, *.CPT, HIGH ``` 这会使用你副本中的 `cpt/*.CPT` 图像、`font_ega.bin` HUD 字体和你的 `HIGH` 分数文件,填充(从未提交的)`assets/` 目录。它还会切分出 `dgroup.bin`,引擎不再读取该文件 —— 它只是为了让 `tools/waveasm.py --verify` 能够将自带的关卡脚本与你自己的原始副本进行交叉核对。 ## 构建与运行 原生环境(需要 SDL2 + CMake): ``` cmake -S src -B build cmake --build build FF2_ASSETS=assets ./build/ff2game ``` 浏览器(需要 [emscripten SDK](https://emscripten.org)): ``` ./build_wasm.sh # emits web/index.{html,js,wasm,data} # 使用任意 static file server 提供 web/ 服务并打开 index.html ``` ## 操作说明 | 操作 | 键盘 | 移动端 | |---|---|---| | 转向 / 加速 / 刹车 | `←` `→` / `↑` / `↓` | 虚拟摇杆(左侧) | | **FIRE** —— 机枪;在菜单中:投币 | `Space` 或 `Ctrl` | 🔫 按钮 | | **START·FLY** —— 开始;在油门全开时:起飞 / 降落 | `Enter` 或 `Shift` | ▲ 按钮 | | **MISSILE** —— 同时按下 FIRE+START(消耗燃料) | 组合键 | 🚀 按钮 | | 重启(网页端) / 退出(原生端) | `Esc` | — | 在触摸设备上,屏幕控制会自动出现(在 URL 后追加 `?touch` 可强制显示)。右上角有一个全屏按钮。 ## 项目结构 ``` src/ the reconstructed engine (C11), one module per original subsystem src/game/data/ the DGROUP game‑logic data, reconstructed as typed C source src/CMakeLists.txt wave/ level scripts in the recovered wave DSL (source of wave_data.c) tools/ reconstruction tooling (wave (dis)assembler, extractors, Ghidra scripts) web/ browser shell (HTML/CSS/JS + vendored nipplejs for the touch joystick) scripts/ graphics extraction from your own game copy build_wasm.sh WebAssembly build assets/ your copy's graphics, created by scripts/extract_assets.sh (never committed) ``` 源文件中包含详细的出处注释:每个例程都引用了它所重构的原始 函数(segment:offset 地址)以及使用的证据。 ## 重构数据与工具 原版游戏将其关卡脚本和查找表保存在可执行文件的 DGROUP 数据 段中。该项目并没有在运行时加载该二进制数据块,而是将其重构为 可读的、**强类型的 C 语言源码**,位于 `src/game/data/` 目录下 —— 包括敌人原型、变形和 sprite 合成器程序、调色板、面板文本、道路曲线、sine/perspective LUT、RNG 种子、演示输入录制等。这就是使构建实现 自包含的原因。 最有趣的部分是**关卡/波次脚本**。原版游戏内置了 专用的脚本 VM —— 其关键字表(`CLEAR`、`GETCHAR`、`PUT`、`WAVE`、`GOSUB`……) 仍然保留在数据段中。我们恢复了那种小语言: - `tools/wavedis.py` 将原始 DGROUP 字节码**无损反汇编**为 位于 [`wave/levels.wave`](wave/levels.wave) 的人类可读 DSL —— 包括助记符、敌人名称 符号、标签,甚至被剪切/无效的脚本也作为 `DEFB` 被逐字保留; - `tools/waveasm.py` 将 `wave/levels.wave` **汇编**回字节,并生成 引擎执行的 `src/game/data/wave_data.c`。该往返过程与 原始文件进行了**字节级验证** —— 全部 3090 个字节码字节以及关卡 目录重组后完全一致。 因此,`wave/levels.wave` 是关卡设计的可编辑事实来源,而已提交的 `wave_data.c` 是其构建产物(使用 `tools/waveasm.py wave/levels.wave --c src/game/data/wave_data.c` 重新生成)。`tools/` 中的其他工具是 `pp20_unpack.py` / `bob_extract.py`,它们是用于 CPT 图像的独立解码器。参见 [`tools/README.md`](tools/README.md)。 ## 法律声明 这是一个非官方的粉丝保护 / 研究项目,不隶属于或受到 版权所有者的认可。*Fire & Forget II* 及所有原始游戏内容均为 其各自所有者的财产。本仓库**不提供任何原始的二进制文件或图像** —— 没有 可执行文件,没有 CPT 画面/sprite,没有字体;你必须拥有原始游戏,并从你自己的副本中提取 这些内容才能进行游戏。引擎及其数据表是对反汇编游戏的原始 转写,仅出于教育和保护目的提供。 [nipplejs](https://github.com/yoannmoinet/nipplejs) 基于 MIT 许可协议。
标签:AI工具, Bash脚本, 客户端加密, 身份验证强制, 逆向工具