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, 二进制翻译, 云资产清单, 代码生成, 单元测试, 性能优化, 数据擦除, 检测绕过, 模拟器开发, 渗透测试工具, 游戏模拟, 游戏移植, 硬件模拟, 运行时系统, 逆向工程, 静态重编译, 音频模拟