前情
改《月下夜想曲》绕不开一件事:光盘里的文件是只读的,容量卡死。
想给某个 Boss 加一段新代码?原文件里往往连十几条指令的空洞都没有。想换一张图?文件大小写死在 ISO 目录里。很长一段时间里,改造只能做「等长替换」——原位改几个字节,多一点都放不进去。
直到把 ISO 重打包这条路打通,才有了「追加数据、改目录、让加载器按新大小复制」的能力。这篇记录过程中的四个坑,每一个都足够让人卡一整天。
工具
用的是 mkpsxiso 2.30:
mkpsxiso
dumpsxiso.exe 解包 ISO → 文件 + project.xml
mkpsxiso.exe 用 project.xml 重新打包
坑一:路径不能有中文
dumpsxiso 是老程序,不支持 Unicode 路径。放在中文目录下会「假成功」——打印 Done,但文件根本没写出来。
所以工作目录必须是纯英文,比如 C:\psx_dump\。
这一条没有报错、没有警告,纯粹靠事后发现目录是空的才知道。第一次踩的人一定会怀疑人生。
坑二:必须加 -l
dumpsxiso.exe -l -x C:\psx_dump -s C:\psx_dump\project.xml 'game.cue'
-l 的作用是把原始 LBA 写进 XML,打包时按原位置放文件。
不加会怎样?文件会被自动重排,然后游戏卡在厂商 logo,一动不动。这个现象特别有迷惑性,因为它看起来像是「镜像做坏了」,实际只是文件位置变了。
坑三:尾部的 dummy 区域不是空的
dumpsxiso 会在 XML 里写这么一行:
<dummy sectors="18731" type="0" offs="231755"/>
看到 dummy 两个字,很容易当成填充垃圾。但这 18731 个扇区是开场动画 / XA 数据。打包时如果按零填充,结果还是卡 logo。
正确做法是从原盘按扇区切出来,当成普通文件塞回去:
// 起始扇区 231755,长度 18731 扇区
const bytes = 18731 * 2352;
// 读原盘 offset 231755*2352,写到 PAD_RAW.BIN
然后 XML 改成:
<file name="PAD_RAW.BIN" source="C:/psx_dump/SD/PAD_RAW.BIN" type="data" offs="231755"/>
坑四:那个音轨是假的
原盘的 cue 只有一条数据轨,但 dumpsxiso 会多生成一条 audio track,pregap 还是个非法值:
<track type="audio" trackid="02" source=".../CD1.WAV">
<pregap duration="954433:04:64"/>
</track>
打包直接报错。处理方式是把整个 audio track 段和 CD1.DA 文件行删掉。
完整流程
1. 解包(英文路径 + 保留 LBA)
dumpsxiso.exe -l -x C:\psx_dump -s C:\psx_dump\project.xml 'game.cue'
2. 手工修 XML:
- 删除 audio track
- 删除 CD1.DA
- dummy 18731 → PAD_RAW.BIN
3. 改文件(比如替换 BOSS\RBO7\RBO7.BIN)
4. 打包
mkpsxiso.exe -y -o C:\psx_dump\rebuild.bin C:\psx_dump\project.xml
5. 写 cue
FILE 'rebuild.bin' BINARY
TRACK 01 MODE2/2352
INDEX 01 00:00:00
验证
| 检查 | 结果 |
|---|---|
| 镜像大小 | 595,683,984 字节(比原盘多 2780 扇区) |
| EXE 位置 | 扇区 24,与原盘一致 |
| 启动 | 过 logo,能玩 |
| 声音 | 待详细测试 |
真正的价值:终于有代码空间了
打通重打包之后,可以做三件以前做不了的事:
- 给任意文件追加数据(比如往 RBO7.BIN 后面写一段新代码);
- 重新打包,ISO 目录会写入新的文件大小;
- 游戏加载器按新大小复制——代码进了内存,就能执行。
之前所有的「代码注入」都卡在没有空间这一步。现在只要改三处就能扩容:
- 原文件尾部追加代码,放到光盘末尾的空闲 LBA;
- 改 DRA 表项:+0 是 LBA,+4 是长度;
- project.xml 里追加一条 file,offs 指向新 LBA。
实际用掉的 LBA:RBO7X 从 250487 起、长度 0x22D40;RBO4X 从 250560 起、长度 0x26800;下一个可用从 250637 之后(整盘共 253267 扇区)。
一个容易忽略的坑
覆盖层尾部不一定是空的。
RBO4 的 0x246E4 到 0x2539F 看着像空闲区,实际是 BSS——代码里有引用 0x801A46E8 / 46F8 / 5360 这些全局变量。往那儿写代码,等于把全局变量覆盖掉,症状会非常诡异。
判断方法:搜代码里对该地址区间的 lui + 偏移引用。或者干脆把钩子放到原文件末尾之后再远一点的地方(RBO4 用的是 0x26400 / 0x26700),并同步改 DRA 的长度。
注意
- 每次改动都要重新打包,不能再用 CDmage 那种等大小替换;
- 打包 589MB 大约 1 到 2 分钟,改一次等一次,习惯就好。
系列文章
