PS1Recomp/ps1-recomp
GitHub: PS1Recomp/ps1-recomp
一个将PS1游戏二进制文件静态重编译为PC原生代码的工具,旨在实现高效、独立的运行与深度逆向分析。
Stars: 0 | Forks: 0
# PS1Recomp
**针对 PlayStation 1 游戏的静态重编译器 -- 将 MIPS R3000A 机器码翻译为可在 PC 上运行的原生 C++ 代码。**
## 概述
PS1Recomp 通过静态重编译,将 PS1 游戏二进制文件转换为原生 PC 可执行文件。它不像传统模拟器那样在运行时逐条解释 MIPS 指令,而是在编译时将整个游戏二进制文件翻译为 C++,并将其链接到硬件模拟运行时。最终生成的是一个独立运行的原生可执行文件,能以 CPU 的全速运行。
```
PS1 ISO/BIN
|
v
ps1Analyzer -> game_config.toml (function boundaries, PsyQ signatures)
|
v
ps1Recomp -> recompiled_out.cpp (MIPS -> C++, ~150k lines per game)
|
v
ps1Runtime -> Native PC executable (SDL2 + OpenGL)
```
## 架构
| 组件 | 目录 | 描述 |
|--------------|------------------|----------------------------------------------------------------------|
| **ps1Analyzer** | `ps1Analyzer/` | 解析 PS1 ELF/BIN,检测函数边界,识别 PsyQ SDK 签名,生成 TOML 配置文件 |
| **ps1Recomp** | `ps1Recomp/` | 解码 MIPS R3000A 指令并生成字面 C++ 翻译(每条指令 1:1 对应),处理 GTE 协处理器和跳转表 |
| **ps1Runtime** | `ps1Runtime/` | 模拟 PS1 硬件:BIOS HLE、GPU (OpenGL 3.3)、SPU (SDL2 音频)、CD-ROM、DMA、GTE、MDEC、定时器、输入 |
| **ps1Interface**| `ps1Interface/ | GUI 工作室,用于加载 ELF、浏览函数、编辑配置和预览重编译后的 C++ 代码 (ImGui + SDL2) |
| **ps1Test** | `ps1Test/` | 557 个单元测试和集成测试,覆盖所有运行时子系统 |
## 项目结构
```
ps1-recomp/
+-- ps1Analyzer/ ELF parser, function finder, PsyQ signature DB, disc reader
+-- ps1Recomp/ MIPS decoder, C++ emitter, GTE emitter, overlay handler
+-- ps1Runtime/ Full PS1 hardware simulation + SDL2/OpenGL host
| +-- src/
| +-- bios/ BIOS HLE (syscall tables A/B/C, heap, events, file I/O)
| +-- cdrom/ CD-ROM emulation (ISO 9660, CUE/BIN, virtual FS)
| +-- gpu/ GPU state machine + OpenGL renderer
| +-- spu/ Sound Processing Unit (24-voice ADPCM)
| +-- mdec/ Motion Picture Decoder (FMV video)
| +-- dma/ DMA controllers (Ch0-Ch6)
| +-- timers/ Hardware timers
| +-- psyq/ PsyQ middleware HLE (VSync, DrawSync, DrawOTag, etc.)
| +-- main_host.cpp SDL2 host: game loop, input, VBlank thread
+-- ps1Interface/ GUI studio (ImGui docking): ELF explorer, function inspector,
| | C++ preview, config editor, Ghidra CSV import
| +-- include/
| | +-- StudioState.hpp Async state management (analysis, config, exports)
| | +-- GUI.hpp 4 dockable panels + menu bar
| | +-- ui/StyleManager.hpp Dark/Light/Custom themes and font scaling
| +-- src/
| +-- main.cpp SDL2 + OpenGL3 entry point with ImGui docking
| +-- StudioState.cpp ps1Analyzer backend integration
| +-- GUI.cpp Panel rendering and keyboard shortcuts
| +-- ui/StyleManager.cpp
+-- ps1Test/ Unit tests (GTest): 557 tests across all subsystems
+-- third_party/ External dependencies: ELFIO, toml11, fmt, googletest
+-- tools/
| +-- extract_psyq_signatures.py Build the PsyQ signature DB from PsyQ SDK .LIB files
| +-- psyq_lib_extract.py Split SN Systems .LIB archives into per-function .OBJ
| +-- ps1_mcp_server.py MCP server for AI-assisted debugging
| +-- run_and_report.py Automated game diagnostics (VRAM, frame rate, logs)
| +-- validate_game.py Pixel-content validation against a frame budget
| +-- demo_build.sh Quick-start demo script
| +-- ghidra/ Ghidra integration scripts
| | +-- ExportPS1Functions.py Export function list from Ghidra to CSV
| | +-- ExportPS1Functions.java Same, Java version (headless mode)
| | +-- start_ghidra_mcp.sh Launch Ghidra with GhidraMCP on port 8080
| +-- pcsx_redux_mcp/ PCSX-Redux emulator integration (MCP server)
+-- .github/workflows/ci.yml CI/CD: build + test on every push
+-- CMakeLists.txt C++20 / CMake 3.20+ build system
+-- LICENSE GPLv3
```
## 构建
### 前置条件
```
# Ubuntu / Debian
sudo apt install cmake build-essential libsdl2-dev libgl-dev
# macOS
brew install cmake sdl2
```
### 克隆与构建
```
git clone --recurse-submodules https://github.com/Dellareti/ps1-recomp.git
cd ps1-recomp
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
```
### 构建带 GUI 工作室的版本(可选)
```
cmake -B build -DCMAKE_BUILD_TYPE=Release -DPS1RECOMP_BUILD_INTERFACE=ON
cmake --build build -j$(nproc)
./build/ps1Interface/ps1Interface
```
### 运行测试
```
ctest --test-dir build --output-on-failure -j$(nproc)
```
## 运行游戏(以 Rayman 为例)
1. 将你的光盘镜像放在任意位置并记录路径:
# 示例路径 -- 请使用适合你的路径:
/home/user/games/Rayman (USA).cue
~/roms/Rayman (USA).cue
./my_games/Rayman (USA).cue
2. 分析二进制文件并生成配置:
./build/ps1Analyzer/ps1Analyzer "/path/to/Rayman (USA) (Track 01).bin.boot.exe" rayman_config.toml
3. 编辑 `rayman_config.toml` 以设置你的光盘路径:
[disc]
cue_path = "/path/to/Rayman (USA).cue"
4. 重编译 MIPS -> C++:
./build/ps1Recomp/ps1Recomp rayman_config.toml ps1Runtime/src/recompiled_out.cpp
5. 构建并运行:
cmake --build build -j$(nproc)
./build/ps1Runtime/ps1Runtime --config rayman_config.toml
## 工作原理
### 阶段 1 -- 分析 (`ps1Analyzer`)
- 读取光盘镜像 (ISO 9660 / CUE+BIN) 并提取 PS1 可执行文件
- 解析 ELF 段:`.text` (MIPS 代码)、`.data`、`.bss`
- 通过序言模式和调用图分析检测函数边界
- 通过签名匹配识别 PsyQ 中间件调用
- 输出包含所有函数地址和 BSS 布局的 TOML 配置文件
### 阶段 2 -- 重编译 (`ps1Recomp`)
- 解码每条 MIPS R3000A 指令(32 位固定宽度)
- 使用 `recomp_context` 结构体作为寄存器文件,为每条指令生成等效的 C++ 代码
- 通过 LUI+ADDIU+ADDU+LW+JR 模式检测跳转表(switch 语句)
- 通过 `gte_emitter` 单独处理 GTE 协处理器指令
- 生成单个 `recompiled_out.cpp` 文件,其中每个 MIPS 函数对应一个 C++ 函数
### 阶段 3 -- 运行时 (`ps1Runtime`)
- **BIOS HLE**:无需 BIOS ROM 即可实现 PS1 系统调用表 A/B/C
- **GPU**:解释 GP0/GP1 命令,将多边形/线段/矩形光栅化到 VRAM (1024x512),通过 OpenGL 3.3 着色器渲染
- **CD-ROM**:模拟驱动器状态机,通过 ISO 9660 从 CUE/BIN 文件读取扇区
- **SPU**:24 声道 ADPCM 音频,通过 SDL2 音频回调混合
- **DMA**:在 RAM、GPU、SPU、MDEC 和 CD-ROM 之间传输数据
- **GTE**:用于 3D 顶点处理的几何变换引擎
- **PsyQ HLE**:使用原生实现替换 PsyQ 中间件函数 (VSync, DrawSync, DrawOTag, SetDefDispEnv, PutDispEnv, PutDrawEnv)
### GUI 工作室 (`ps1Interface`)
- **资源管理器面板**:列出所有函数,以颜色编码策略(PsyQ=黄色,存根=红色,跳过=灰色,强制重编译=绿色),可按名称筛选
- **检查器面板**:显示函数详情(地址、大小、反汇编摘要),并允许更改每个函数的重编译策略
- **工作区面板**:标签式视图,包含 C++ 预览、十六进制转储、config.toml 编辑器和 Ghidra CSV 导入器
- **日志面板**:实时分析进度条和错误标记
- 键盘快捷键:`F5` = 分析,`Ctrl+O` = 打开 ELF,`Ctrl+S` = 保存配置
## 关键设计决策
**静态与动态重编译**:所有翻译在编译时完成 -- 无 JIT,无解释器循环。游戏代码作为常规 C++ 函数调用以原生 CPU 速度运行。
**HLE 优于 LLE**:BIOS 和 PsyQ 中间件被实现为高级仿真 (HLE) 存根,而不是运行原始 ROM 代码。这避免了法律问题并简化了运行时。
**基于哈希的 PsyQ 检测**:`ps1Analyzer` 将每个函数体与从 14 个 SDK 版本(3463 个签名,碰撞过滤后 1943 个唯一签名)中提取的 PsyQ SDK 函数 SHA-256 数据库进行匹配。检测到的函数在运行时被路由到原生 HLE 实现,而不是被重编译。这避免了针对特定游戏的命令式补丁,也是该项目与先前 PS1 重编译器的主要区别。
**双缓冲帧缓冲**:PS1 游戏通常在 VRAM 中使用双缓冲(例如,Buffer A 在 (0,0) 渲染时,Buffer B 在 (0,256) 显示,每 60Hz 的垂直消隐期间交换)。运行时从 GPU 命令流推断活动显示窗口。
## 工具
### GUI 工作室
```
./build/ps1Interface/ps1Interface
```
打开可视化工作室,用于加载 ELF 文件、浏览函数、编辑游戏配置以及在运行完整流程之前预览生成的 C++ 输出。
### Ghidra 集成
项目包含用于静态分析验证的 Ghidra 脚本:
- 安装 `ghidra_psx_ldr` 插件(PSX 专用加载器,支持 GTE + PsyQ)
- 在 Ghidra 中运行 `tools/ghidra/ExportPS1Functions.py` 将函数边界导出为 CSV
- 运行 `tools/ghidra/start_ghidra_mcp.sh` 启动带 MCP 桥接的 Ghidra(端口 8080)
### 自动化诊断
```
python3 tools/run_and_report.py --duration 15 --output /tmp/report.json
```
运行游戏 N 秒,并输出包含帧率、VRAM 像素分析、GPU 命令日志和 CD-ROM 回调计数的 JSON 报告。
## 依赖项
| 库名 | 用途 | 引入方式 |
|-----------------------|--------------------------|-------------------------------|
| [ELFIO](https://github.com/serge1/ELFIO) | ELF 二进制解析器 | Git 子模块 |
| [toml11](https://github.com/ToruNiina/toml11) | TOML 配置解析器 | Git 子模块 |
| [fmt](https://github.com/fmtlib/fmt) | 字符串格式化 | Git 子模块 |
| [GoogleTest](https://github.com/google/googletest) | 单元测试框架 | Git 子模块 |
| [Dear ImGui](https://github.com/ocornut/imgui) | GUI(docking 分支) | FetchContent(仅 ps1Interface) |
| [ImGuiColorTextEdit](https://github.com/BalazsJako/ImGuiColorTextEdit)| 语法高亮代码编辑器 | FetchContent(仅 ps1Interface) |
| [ImGuiFileDialog](https://github.com/aiekick/ImGuiFileDialog) | 原生文件打开/保存对话框 | FetchContent(仅 ps1Interface) |
| SDL2 | 音频 (SPU) + 窗口 + 输入 | 系统包 |
| OpenGL 3.3 | GPU 渲染后端 | 系统包 |
## 灵感来源
- [N64Recomp](https://github.com/N64Recomp/N64Recomp) -- 开创了针对复古游戏机的静态重编译方法
- [PS2Recomp](https://github.com/ran-j/PS2Recomp) -- 直接的架构参考(ps2Analyzer/ps2Recomp/ps2Runtime 结构)
- [psxrecomp](https://1379.tech/i-built-a-ps1-static-recompiler-with-no-prior-experience-and-claude-code/) -- PS1 静态重编译器参考实现
- [Nocash PSX Specs](https://problemkaputt.de/psx-spx.htm) -- 权威的 PS1 硬件参考手册
- [ps1-bare-metal](https://github.com/spicyjpeg/ps1-bare-metal) -- PS1 硬件编程示例
## 现状
该项目是一项进行中的本科毕业设计课题。**它不是一个完成的模拟器** -- 它是一个架构端到端工作的重编译器,外加一个覆盖足够多 PS1 硬件以启动真实游戏的运行时。老实说,目前的状态是:
- **流程**:稳定。分析器 -> 重编译器 -> 运行时 -> 原生二进制文件适用于任何 PS1 ELF/EXE。存根模式构建(无 ROM)是 CI 基线(557/557 测试通过)。
- **Rayman (USA)**:是贯穿阶段 0-3 的主要验证目标。使用先前的命令式 HLE 补丁时,它能以约 59fps 运行,且 VRAM 内容正确。这些补丁在开源准备期间已被移除;现在重新生成的路径完全依赖基于 PsyQ 哈希的 HLE 覆盖范围,自补丁移除后尚未重新进行端到端验证。
- **Crash Bandicoot 1 (USA)**:实验性支持。能通过 PsyQ 初始化启动,但随后在游戏侧的哈希表遍历中停滞;针对短 libcd 包装器的签名匹配器 bug 是下一个已知的阻碍(参见 `PLANNING.md` 阶段 4 说明)。
- **其他游戏**:尚未测试。该架构旨在与游戏无关;添加新游戏主要是提供 TOML 配置文件并运行分析器的问题。
关于哪些能工作、哪些不能工作的详实、逐点的说明,请参阅 `ARCHITECTURE.md`。
## 许可证
GPLv3
标签:Bash脚本, BIOS模拟, C++, CD-ROM模拟, GPU模拟, GUI工具, MIPS架构, OpenGL, PC游戏, PlayStation 1, SDL2, 二进制翻译, 云资产清单, 代码生成, 单元测试, 性能优化, 数据擦除, 检测绕过, 模拟器开发, 渗透测试工具, 游戏模拟, 游戏移植, 硬件模拟, 运行时系统, 逆向工程, 静态重编译, 音频模拟