ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

gow3_pc运行时原理:387个PS4系统API如何被逐一重写,从音频到存档全实现

gow3_pc运行时原理:387个PS4系统API如何被逐一重写,从音频到存档全实现

【免费下载链接】gow3_pc

God of War III Remastered (PS4) for Windows and Linux (experimental AppImage). Original x86-64 code runs directly on the CPU with a custom runtime; graphics use shadPS4's Vulkan video core and cuesta4's fixes. Launcher, in-game menu, controller icons and up to 240 FPS. Requires your own game dump. No game files included.

项目地址:https://gitcode.com/gh_mirrors/go/gow3_pc
点击查看免费下载

gow3_pc 是一个《战神3 重制版》(God of War III Remastered, PS4)的 PC 移植项目,其核心是一个自研的gow3_pc 运行时:游戏原版 x86-64 代码直接在 PC 处理器上原生运行,而运行时逐一手写的 387 个 PS4 系统 API 替代了整台 PS4 主机——从内存、线程、文件系统,到音频解码、视频过场、手柄和存档,全部重新实现,没有任何模拟器。

为什么不是模拟器:原生运行 + 系统层替换

关键前提:PS4 本身就是一台 x86-64 电脑。《战神3》的eboot.bin编译出的指令集与 PC 完全兼容,所以游戏代码一个字都不用改,直接在你的 CPU 上跑。

项目真正要做的是"在游戏的周围伪造一台 PS4":

部分位置作用
准备阶段scripts/读取eboot.bin,应用重定位,把游戏自带的 libc、libSceFios2 链接成一张镜像
加载器src/probe.c把镜像载入内存、绑定全部导入、装好钩子并进入游戏原版代码
运行时src/runtime_*.c重实现 PS4 系统函数:内存、线程、文件、音频、视频、手柄、存档、服务
图形gpu/shadps4/shadPS4 视频核心,把 PS4 GPU 指令和着色器翻译成 Vulkan

图形侧由 shadPS4 负责,本文聚焦 CPU 侧的运行时。

第一步:用 NID 哈希盘点 387 个系统 API

PS4 的库导入不直接用函数名,而是用一段随机"哈希"(NID)。在 src/import_names.inc 里可以看到这种对应关系:

{"bzQExy189ZI#libc","_init_env"}, {"7H0iTOciTLo#libkernel","pthread_mutex_lock"},

加载器按NID#库名去解析每一个重定位项,把哈希换回真实函数名。项目提供了一条不启动游戏就能清点 API 的命令:

gow3-probe.exe out/boot-linked.bin --app0 <游戏目录> --check-imports

在 CUSA01623 v01.02 的 dump 上,这条命令盘点了387 个导入:最初 45 个没有实现(35 个由游戏直接调用,10 个只被 libc/Fios2 引用),清单记录在 docs/gow3/ROADMAP.md 的"Etapa 3"一节。此后这 45 个被逐一补齐,现在--check-imports的 missing 数为 0。

值得一提的是加载器的"不兜底"哲学:每个未解析的导入都会被绑到一段 32 字节的陷阱 stub,一旦游戏真的跳进去,程序立刻打印STOP: first unsupported PS4 import并退出(见 src/probe.c 的unresolved处理)。绝不提供"假装成功"的空桩——宁可停下来告诉你缺什么,也不悄悄返回假数据。

逐一重写:16 个模块对号入座

src/runtime.c 中的runtime_resolve是总调度:拿到一个导入名后,按顺序询问各子系统的解析器,谁认领谁实现:

mutex → thread → content → time → sema → rwlock → memory → kernel → services → ajm → videodec → audio → pad → rtc → savedata → file → GPU库

每个模块负责一块 PS4 系统能力:

子系统模块实现方式
虚拟内存runtime_memory.cPS4 direct pool 用单个稀疏 memfd 打底(Windows 用 pagefile section),任意物理区映射共享同一存储
线程runtime_thread.c游戏线程跑在宿主 pthread 上,每个线程拥有 FreeBSD 风格 TCB;Linux 占用 GS 段基址,Windows 塞进 TEB 的 TLS 槽
互斥/信号量/读写锁runtime_mutex.c、runtime_sema.c、runtime_rwlock.cpthread 互斥锁、32 位 ID + FIFO 等待队列、Linux rwlock,全部对齐 PS4 的指针-句柄 ABI
进程服务runtime_kernel.c时钟、睡眠、pthread_once/key、sysctl;errno 按 FreeBSD 编号映射,宿主的 errno 值永远不会直接漏给游戏
时间runtime_time.c、runtime_rtc.ctimeval显式布局;RTC 采用 PS4 惯例——自公元 0001-01-01 起的微秒计数
文件系统runtime_file.c把/app0、/temp0、/download0等挂载点映射到宿主目录;含..的路径直接拒绝
音频解码runtime_ajm.cATRAC9 由 LibAtrac9 解码,MP3 由 FFmpeg 解码(runtime_mp3.c),批次同步提交、同步完成
音频输出runtime_audio.clibSceAudioOut 架在 SDL3 音频流上,25 个端口、7.1 下混
视频解码runtime_videodec.cFFmpeg 把 H.264 过场解成游戏指定的 NV12 帧缓冲
手柄runtime_pad.cSDL3 手柄 + 键盘回退,DualSense、Xbox 及通用手柄,键位可重映射
存档runtime_savedata.clibSceSaveData 落到宿主目录,元数据放在存档目录旁边
系统服务runtime_services.c离线单用户主机的全部"合同"

每次运行结束时,runtime_report会汇总各模块的调用计数(内存操作数、线程数、pad 读取次数等),这些数字也是调试时的重要线索。

音频:两种解码器 + 无爆音输出节奏

《战神3》同时用 ATRAC9 和 MP3,两种解码器都由运行时接管。runtime_audio.c 有一段很见功力的注释:游戏的 FMOD 混音线程每次读取 256 帧,如果sceAudioOutOutput按设备实际拉数据的节奏突发返回,输出线程会"超车"混音器,每 10.7 毫秒就爆一下音。运行时因此让输出线程按稳定时钟逐周期返回,并用 SDL 队列水位控制吸收设备时钟漂移。

另一处细节是 7.1 下混:SDL 自带矩阵把前置声道压到约 -13.5 dB,游戏会变得非常安静;运行时自己实现下混——前置全量、中置与环绕 -3 dB、丢弃 LFE 再限幅。

存档:一个目录就是 PS4 存档格

存档直接映射到宿主文件夹,结构严格模仿 PS4(见 runtime_savedata.c 顶部注释):

<user>/savedata/1/CUSA01623/<存档目录>/ 游戏写入的文件 <user>/savedata/1/CUSA01623/<存档目录>.sce_sys/ param.bin、icon0.png

元数据(标题、图标等 1328 字节的OrbisSaveDataParam)放在目录旁边,绝不污染游戏自己的文件。存档列表对话框则在游戏内以覆盖层显示,与 PS4 上的表现一致。

系统服务:伪造一台"离线单机主机"

runtime_services.c 的开头就写明了整个合同:一个 id 为 1 的本地用户已登录但未登录 PSN;网线"没插",NetCtl 断连、socket 不可用;系统对话框立即完成;整包游戏已安装完毕(PlayGo 报告每个 chunk 都在本地)。PSN 相关 API 一律返回"未连接",从不假装在线——未知函数仍然直接 STOP,这条边界保证了移植的可信度。

如何验证:导入检查与测试套件

想确认"游戏用到的每个系统函数都被实现了",无需真正启动游戏,跑一遍导入检查即可(见 README.md 的 Tests 一节):

gow3-probe.exe out/boot-linked.bin --app0 <游戏目录> --check-imports

退出码为 1 且打印MISSING:行说明仍有缺口。项目测试同样按子系统划分:tests/test_runtime.c、tests/test_mp3.c、tests/test_videodec.c、tests/test_audio_downmix.c、tests/test_pad.c、tests/test_sema.c、tests/test_services.c,跑法是python -m unittest discover -s tests加bash build.sh --test。

相关资料

  • 总览与构建说明:README.md
  • 进度与 API 盘点清单:docs/gow3/ROADMAP.md
  • 运行时入口与总调度:src/runtime.c、src/probe.c
  • NID 与符号对照表:src/import_names.inc
  • 内存/线程/文件/存档实现:src/runtime_memory.c、src/runtime_thread.c、src/runtime_file.c、src/runtime_savedata.c
  • 音频与视频解码:src/runtime_ajm.c、src/runtime_mp3.c、src/runtime_audio.c、src/runtime_videodec.c

小结:gow3_pc 的运行时本质上是一份"PS4 系统 API 的逐条重写清单"——387 个导入逐一落到 16 个模块,音频、视频、存档、手柄、服务无一例外;配合"未知即 STOP、检查可离线"的工程纪律,这份清单既是实现,也是可验证的完成度证明。

【免费下载链接】gow3_pc

God of War III Remastered (PS4) for Windows and Linux (experimental AppImage). Original x86-64 code runs directly on the CPU with a custom runtime; graphics use shadPS4's Vulkan video core and cuesta4's fixes. Launcher, in-game menu, controller icons and up to 240 FPS. Requires your own game dump. No game files included.

项目地址:https://gitcode.com/gh_mirrors/go/gow3_pc
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进