
revd - 为GTA IV增加更多引擎音频槽位
GTA IV 为每种不同车辆模型分配一个引擎音效,且仅有二十五个槽位可供放置,因此在交通流量包中大多数车辆驶过时都是静音的。revd 将该上限提升至六十四个。一份研究发布文档,记录了音效表、重定位操作以及哪些内容被测量、哪些未被测量。
查看大图[size=5][b]revd:为 GTA IV:完整版增加更多引擎音频槽位[/b][/size]
[i]研究性发布。源码、数据与问题反馈:[url=https://github.com/gutbash/revd]github.com/gutbash/revd[/url][/i]
[size=4][b]摘要[/b][/size]
GTA IV 在可听范围内为每个不同的车辆[b]模型[/b]分配一个循环引擎音效,而不是为每辆车分配,并将这些分配存储在一个固定的二十五条目表中。在干净安装中这个限制是不可见的,因为原版交通流很少同时出现二十五个不同模型;但在使用交通包时会变得明显,第二十五个之后的模型不会被分配槽位,完全不会产生引擎音效。该表无法就地扩展,因为无关的静态数据紧接在其后占用内存。revd 将该表迁移到自己的映像中,重新指向对其的全部十四个绝对引用,提高探测循环的边界,并提高用于划分槽位块的物理音频堆。提高堆不是可选项:在原始堆上使用三十个槽位时,游戏会在音频初始化期间崩溃。
[size=4][b]问题[/b][/size]
症状看起来像是音频模组损坏。车辆驶过时悄无声息,而附近其他车辆声音正常,且哪些车辆无声会随交通流变化而改变。其实什么都没有损坏。游戏只是没有地方放置音效了。
位于 RVA 0x58D4C3 到 0x58D512 的音频初始化会按名称向上探测 STREAM_ENGINE_1,并将每个解析出的槽位存储到 0xE832B8 处一个由十六字节条目组成的表中,计数位于 0xE83298。循环在以下条件下终止:
[code]0x58D50D cmp edi, 0x19 二十五[/code]由于探测是按名称进行的,上限由可执行文件和 pc/audio/config/waveslots.xml 共同强制。只提高其中一个而不同时提高另一个不会有任何效果。
[size=4][b]方法[/b][/size]
[b]迁移。[/b]对该表的每个引用都是指向条目零字段的绝对位移,偏移量为 0、4、8 和 12。共有十四个,分布在 0x58B979 到 0x828054。revd 在自己的映像内部分配一个六十四条目表,在三十二字节头部后按十六字节对齐,并重写全部十四个位移。首先会对照预期值验证全部十四个;如果有任何一个不一致,则不写入任何内容。
[b]边界。[/b]位于 0x58D50F 的 imm8 变为配置的槽位数量。
[b]堆。[/b]物理音频堆是位于 0x4C158C 的单个 imm32,原始为 126 MB。revd 将其修补为配置的大小,默认 192 MB。
所有三处写入都必须落在 .text 解密之后、音频系统初始化之前。revd 以 50 毫秒轮询该窗口,验证每个位置,如果窗口先关闭,则让游戏保持原版并记录其已这样做。
[size=4][b]发现[/b][/size]
三项观察,单台机器,2026-09-06:
[list]
[]原始 126 MB 堆上的 25 个槽位:可运行。[/]
[]原始 126 MB 堆上的 30 个槽位:在音频初始化期间崩溃。[/]
[]192 MB 堆上的 64 个槽位:可运行。[/]
[/list]在 waveslots.xml 中,一个引擎槽位声明为 794,624 字节,因此六十四个声明为 48.5 MB,而原始为 19.0 MB。
[b]堆需求是观测所得,而非推导所得。[/b]waveslots.xml 中另外七十个槽位合计声明为 129.2 MB,这本身就已经超过了原始的 126 MB 堆。因此堆并不是声明大小的简单总和,而分配器实际保留了多少从未被测量过。二十五个和三十个槽位之间的崩溃阈值没有被二分定位。请将 192 MB 视为已知可用的值,而不是计算出的需求。
[b]六十四是上限,不是保证。[/b]它意味着游戏可以同时为六十四个不同模型发声。是否实际如此取决于实际存在多少多样性。
[size=4][b]安装[/b][/size]
[list=1]
[]确保存在 ASI 加载器。通常使用作为 dinput8.dll 的 Ultimate ASI Loader,如果你运行 FusionFix,则已经拥有它。[/]
[]将 revd.asi 和 revd.ini 放入你的 GTAIV 文件夹,与 GTAIV.exe 放在一起。[/]
[][b]扩展 waveslots.xml。[/b]见下文。跳过这一步会使插件毫无实际作用。[/]
[]启动。revd.log 会记录每次修补尝试及其结果。[/]
[/list]
[size=4][b]第 3 步,人们常忽略的部分[/b][/size]
游戏按[b]名称[/b]探测槽位,因此 waveslots.xml 未定义的槽位会保持为空,仅提高边界没有任何作用。
[b]简单方法。[/b]从 GitHub 仓库下载 add-engine-slots.ps1 并运行它。它会将缺失的条目追加到你现有的文件中,而不是替换它,因此其他音频模组的更改会保留,它会把原始文件备份为 waveslots.xml.bak,并且可以安全地运行两次:
[code].\add-engine-slots.ps1 -Slots 64[/code]该脚本托管在 GitHub 上,而不是捆绑在下载中,因为 Nexus 的自动检查会隔离任何包含 PowerShell 脚本的压缩包。
[b]手动方法。[/b]打开 pc\audio\config\waveslots.xml,对于从 26 到 64 的每个数字,在闭合标签之前添加一个如下所示的块,只更改数字:
[code] <Slot>
<Name content="ascii">STREAM_ENGINE_26</Name>
<MaxHeaderSize value="2048" />
<LoadType content="ascii">BANK</LoadType>
<Size value="794624" />
</Slot>[/code]请先备份该文件。
[size=4][b]验证[/b][/size]
revd.log 是事实来源。两行日志表示成功:
[code]engine slots: table relocated to 0F2A0120 (14 sites), probe bound 25 -> 64
audio heap: 126 MB -> 192 MB[/code]如果缺少其中任何一行,日志会指出失败的检查。
[size=4][b]限制[/b][/size]
这些是已测试内容的边界。不应假定边界之外的任何内容可用。
[list]
[][b]仅限完整版 1.2.0.59。[/b]每个地址都是该确切版本的硬编码偏移。在任何其他版本上,验证会失败,不会修补任何内容,日志会说明这一点。[/]
[][b]六十四是硬上限[/b],由迁移后表的容量决定。更高的值会被钳制。[/]
[][b]堆数值是经验性的。[/b]它是已知可用的值,不是推导出的值。[/]
[][b]大约三十个槽位以上时,提高堆是强制性的。[/b]只提高数量而不提高堆会在音频初始化期间崩溃。revd 会在加载时警告这种组合。[/]
[][b]修补窗口很窄。[/b]ASI 加载器加载得足够早。较晚注入可能不行,revd 会检测到并保持游戏不变。[/]
[][b]没有音频质量或混音分析。[/b]六十四个同时引擎循环是否会改变混音平衡,或产生可测量的 CPU 开销,未被研究。[/]
[][b]单台机器,单一模组栈。[/b]基于通过 ASI 加载器加载 FusionFix 的单一安装进行开发。[/]
[/list]
[size=4][b]可复现性[/b][/size]
任何复现此内容的人都应报告游戏版本、槽位数量、堆大小以及 revd.log 的内容。未解决的问题是原始堆上的确切崩溃阈值、音频分配器在运行时相对配置声明实际为每个槽位保留多少,以及迁移后的表是否对音频 CPU 成本有任何影响。
[size=4][b]验证你下载的内容[/b][/size]
完整源码在 GitHub 上以 MIT 许可发布,每个二进制文件都由公开的 GitHub Actions 从该源码构建,因此你可以阅读构建日志或自行构建,而不是信任上传内容。它是一个单一翻译单元,除 Win32 SDK 外没有依赖。
revd.asi SHA-256 0e76e726e294eaf861d497bb77d0c12b87137a219124a297065e53c597d3d50d
[size=4][b]配套发布[/b][/size]
[url=https://github.com/gutbash/popctl]popctl[/url] 移动行人和交通移除半径,这是一个单独的限制,有单独的修复。使用 popctl 提高交通多样性正是会把你推向本发布所解除的上限,因此两者值得一起阅读。
[size=4][b]许可证[/b][/size]
MIT。随你喜欢怎么做,包括将其打包进你自己的模组包中发布。
还没有人评论,去客户端里说两句吧。
评论在新手盒子客户端中发表,这里同步展示。