ant0-blase/MOHFrontline-PS2Recomp

GitHub: ant0-blase/MOHFrontline-PS2Recomp

通过静态重编译技术将PS2游戏《荣誉勋章:前线》移植为PC原生可执行文件的逆向工程项目。

Stars: 0 | Forks: 0

Medal of Honor: Frontline

MOH Frontline — PS2 静态重编译

Medal of Honor: Frontline(PlayStation 2,SLUS_203.68)的原生 PC 移植版
通过静态重编译而非模拟方式构建。

游戏的 MIPS R5900 代码被提前翻译为 C++,编译为普通的原生可执行文件,并与手写的 PlayStation 2 硬件接口实现一起运行——包括 VU0/VU1、Graphics Synthesizer、VIF1、DMA 控制器和 I/O 处理器。 基于 [ran-j/PS2Recomp](https://github.com/ran-j/PS2Recomp) 构建。本仓库是针对 Frontline 的专属分支:包含运行时的工作及相关开发笔记。 ## 进度 以下所有内容均由该移植版渲染:没有模拟器,也没有原始可执行文件——完全由重编译后的游戏代码驱动软件 Graphics Synthesizer。
Publisher logo Title screen
Cold boot. The publisher logo plays from the game's own video stream, with audio. Title screen. Textured plaque, alpha blending and the front-end font pipeline.
June 6, 1944 Opening text
Level opening. "Your Finest Hour" opens on its date card and text, over the soundtrack.
Main menu Mission Log, D-Day
Main menu. The campaign desk, with its map, compass and layered paper sprites. Mission Log. Mission detail, medal criteria and save/load entries.
Enigma code entry All missions unlocked
Code entry. The Enigma machine screen, here with the retail DAWOIKS cheat. …and it takes. All six campaigns unlocked, so the whole mission tree is reachable.
Rough Landing loading screen Loading banner
Level load. "Rough Landing" — mission title, artwork and a live progress bar. Loading banner. The between-screens transition.
Normandy fleet, in engine
In engine. The invasion fleet off Omaha Beach — recompiled game code driving a software Graphics Synthesizer. The banding across the water is the open defect below.
**已实现功能** - 冷启动并通过发行商 Logo 和开场动画——包含视频和音频。 - 前端界面:标题画面、主菜单、任务日志、简报画面、字体、HUD 精灵图。 - 通过 Enigma 界面输入代码,包括正式版的关卡解锁作弊码。 - 任务加载、加载画面,以及带有纹理、雾效和 Z 缓冲的第一个 3D 场景。 - 通过 IOP HLE 层流式传输音乐和音效。 - VU0 宏模式、VU1 微程序解释、VIF1 解包、GIF PATH1/2/3。 **已知缺陷 — 屏幕外几何体** 在 3D 场景中,巨大的剪切三角形会遮挡视野。原因已定位:Frontline 在 VU1 中不执行任何几何裁剪。其微程序改为测试裁剪标志寄存器,并且对于任何接触视锥体的图元,都会设置 **ADC 位**(打包顶点四字的第 111 位),以便 GS 剔除该顶点而不进行绘制。常驻的三个 VU1 微程序中,有一个在此处能正确驱动该路径;另一个则在 ADC 位清零的情况下发射了数百万个视锥体外顶点,而正是这些顶点被绘制了出来。详情请参阅[技术说明](docs/TECHNICAL-NOTES.md)。 ## 构成方式 ``` ps2xAnalyzer scans the ELF, exports a function map (Ghidra-assisted) ps2xRecomp decodes R5900 and emits one C++ function per game function ps2xRuntime the PS2 that generated code runs against ps2xIOP HLE for the I/O processor: CD/DVD, memory card, SPU2, RPC ``` `ps2xRuntime` 是移植工作的核心所在——包含约 120 个文件中的 9.5 万行代码。对 Frontline 而言最重要的部分: | 领域 | 文件 | |---|---| | VU1 微程序解释器(上/下层流水线、裁剪标志、DIV 延迟) | `src/lib/vu/ps2_vu1_*.cpp` | | Graphics Synthesizer 寄存器文件与 GIF 数据包解码 | `src/lib/ps2_gs_gpu.cpp` | | 软件光栅化器(三角形、精灵图、纹理、Z 缓冲、alpha) | `src/lib/ps2_gs_rasterizer.cpp` | | VIF1 命令流、UNPACK、MPG 微代码上传 | `src/lib/ps2_vif1_interpreter.cpp` | | 客户机内存、DMA 标签遍历、暂存器 | `src/lib/ps2_memory.cpp` | | 基于 ELF 元数据的针对单个游戏的运行时补丁 | `src/lib/game_overrides.cpp` | ## 编译说明 需要 CMake 3.20+、支持 C++20 的编译器,以及支持 SSE4 的主机。 ``` git clone --recurse-submodules https://github.com/ant0-blase/MOHFrontline-PS2Recomp.git cd MOHFrontline-PS2Recomp cmake -S . -B build-runtime-launcher -DCMAKE_BUILD_TYPE=RelWithDebInfo ``` 接着,使用你自己的光盘镜像: 1. 从光盘中提取 `SLUS_203.68`。 2. 使用 `ps2xAnalyzer/tools/ghidra/ExportPS2Functions.java` 从 Ghidra 导出函数映射表。 3. 使用 `toml/` 中的配置将其重编译到 `recomp/` 目录中: ./ps2_recomp toml/launcher_recomp.toml 4. 编译并运行: cmake --build build-runtime-launcher --target ps2MOHFrontlineRunner -j$(nproc) ./build-runtime-launcher/ps2xRuntime/ps2MOHFrontlineRunner extracted/SLUS_203.68 `tools-moh-run-capture.sh` 会运行游戏,并按固定间隔对窗口进行截图。`tools-moh-verified-run.sh` 对其进行了封装,并断言链接的二进制文件中确实包含正在测量的诊断探针,从而确保测试结果始终能追溯到生成它的构建版本。 ## 诊断 运行时内置了检测探针,默认全部关闭,且均通过环境变量进行选择,因此无需修改代码即可测试假设: | 变量 | 效果 | |---|---| | `PS2_MOH_DIAG_SPAN_LIMIT=` | 丢弃宽度超过 N 个像素的图元。在裁剪缺陷未解决时可使 3D 场景变得可辨认——但它也会丢弃合法的全屏菜单四边形,因此切勿在前端界面使用。 | | `PS2_MOH_DIAG_CLAMP_XY=1` | 在 `FTOI4` 之前对屏幕的 X/Y 坐标进行截断,而不是让 GS 字段发生回绕。 | | `PS2_MOH_DIAG_NO_TEXTURE=1` | 平面渲染,用于将几何体故障与纹理故障区分开来。 | | `PS2_MOH_VU_DIV_LATENCY=1` | 模拟 VU `DIV`/`WAITQ` 延迟,而不是立即清空 `Q`。 | | `PS2_MOH_DIAG_NO_CF_MASK=1` | 禁用 24 位裁剪标志掩码,用于 A/B 测试。 | 这些是诊断工具,而非修复方案:在正常运行中均未启用,也不会根据关卡、帧或颜色进行条件触发。 ## 技术说明 [`docs/TECHNICAL-NOTES.md`](docs/TECHNICAL-NOTES.md) 涵盖了耗费大量时间的发现及其背后的测量数据。以下是一些不仅局限于本游戏的通用经验: - **`FTOI` 必须执行饱和截断。** 普通的 C++ `float`→`int32_t` 转换在溢出时属于未定义行为,并在 x86 上会导致符号翻转。这*正是*导致 3D 渲染损坏的*核心*缺陷;而 PS2 硬件会进行饱和截断。 - **VU1 微代码库并不稳定。** Frontline 每次运行都会将每个 0x800 字节的 bank 重写约 86 次,循环使用三个不同的程序。任何基于 VU1 地址的统计数据如果未按 `(bank, variant)` 标记,都将毫无意义。 - **GS 的 `Q` 寄存器会在 `RGBAQ` 上锁存**,而不是逐顶点锁存(在 PACKED 模式下)。 - **三角带顶点窗口必须在非绘制剔除时也进行推移** —— `XYZ3` 和 ADC 被抑制的顶点仍会移动窗口。 [`docs/SUBSYSTEM-MAP.md`](docs/SUBSYSTEM-MAP.md) 将游戏的子系统映射到了 ELF 地址,并为每个标签提供了证据。 ## 致谢 - [PS2Recomp](https://github.com/ran-j/PS2Recomp) 作者 ran-j —— 本分支所基于的重编译器和运行时基础。 - 灵感来自 [N64Recomp](https://github.com/N64Recomp/N64Recomp)。 - 感谢 ELFIO、toml11 和 fmt 提供解析与格式化支持。 ## 法律声明 *Medal of Honor: Frontline* 版权所有 © 2002 Electronic Arts Inc. 本项目不包含任何游戏代码和游戏资产:它仅为工具链以及对 PS2 硬件行为的原创重新实现,并且需要您合法拥有的游戏光盘才能运行。重编译器输出是在您的机器上生成的,并已通过 `.gitignore` 从本仓库中排除。上方的截图是该移植版运行时的画面捕获,包含于此仅用于记录其开发状态。
标签:Bash脚本, C++, PlayStation 2, 云资产清单, 数据擦除, 游戏引擎, 游戏移植, 逆向工程, 静态重编译