红楼梦十二金钗游戏资源分析(二十)

我们已经还原了第一个事件图,接下来我们要看看是否能把这个过程带到其他事件图,换句话说, 我们要去解开 Redevent.paf 中的其他图了。

目录

本系列已完结,以下是各章节说明,17 之前是 dos 版相关,之后是 2001 版:

  1. 背景、简单分析
  2. 显存位置
  3. 事件图保存算法: LZW
  4. 调色板
  5. MGP2
  6. 结局图
  7. 事件图中的眼睛
  8. 音频文件
  9. 按位读取
  10. 循环之前
  11. 读取循环
  12. 重现 LZW
  13. PAT 的图形格式
  14. STAFF 调色板
  15. 字体文件
  16. 脚本解密
  17. 版本比较
  18. 第一张图
  19. 调色板1
  20. 第二张图
  21. 调色板2
  22. 调色板处理
  23. 静态事件图、结局图
  24. 动态图、鉴赏模式

前情提要

之前我们确认过第一个事件图的像素数据的开始位置是从 Redevent.paf 0x8a2 开始:

程序也需要知道,到底需要从哪里,把每张图的数据读出来,所以一定另外有一个位置保存了每张图的起点位置。 那么这个数据可能在哪里,我们要对一下文件的读取过程。而且我们知道,有两个时间点读取了文件, 一个是游戏启动时,一个是切换图片时,切换图片时读的是像素数据,那起始位置一定是游戏启动时读出来的了, 所以我们需要看一下启动时,文件是怎么读的。

读取 Redevent.paf

这时候我们又要翻出之前读取文件的日志文件,不过直接看日志可能会比较多,我来整理一下读取的部分:

读取顺序 读取起点 读取字节数
1 00000000 50 (80.)
2 0221BEC0 5AC0 (23232.)
3 00000440 F0 (240.)
4 02207E80 13CE0 (81120.)
5 01D22180 150 (336.)
6 01B65340 2C34 (11316.)
7 01D1D140 4D44 (19780.)
8 0215C180 5C0 (1472.)

从上面的过程来看,最有可能的是 2、4、6、7、8,因为游戏有一百多事件图, 保存一个起始位置需要 4 个 byte,其他数据量不足以保存这么多事件图,所以我们从 2 开始看起。

0221BEC0 + 5AC0

看之前我们先提一下这两个数字是怎么来的,这两个数字其实都来自前 50h 个 byte, 也就是第一次读取的内容:

其中 5AC0h = 16Bh x 40h,也就是说这段数据有 16Bh(363) 个,每条数据 4 行, 看到这里我想可能有读者会说,这个数字和事件图的数量对不上,跳下一组吧,别急, 最初我也是这样判断的,但是后来我发现,PAF 文件包含了之前多个文件的数据, 比如 AREA 就是和 SAREA 放在一起的,所以,数量对不上不能作为我们忽略这组数据的理由, 那我们继续往下,看 0221BEC0 的第一组数据:

上图里有两组数据,前四行就是我们说的第一组数据,老实说,应该是一眼看不出来有什么线索, 除了最后的这个 0840h,因为这个位置比实际数据的位置要靠前,换句话说,它可能包含了像素数据。

我们还可以对比一下显示事件图时,程序读了什么:

读取顺序 读取起点 读取字节数
1 00000880 38C8C (232588.)
2 01B68380 1C69 (7273.)

这个同样很迷对不对,880h 这个数字同样没有出现在上面的数据里,我们只知道它比 840h 小, 现在我们有三个数字了,840h880h8a2h

不过这几个数据比较近,我们可以看看 840h 开始保存了什么:

看上去似乎 840h 有指向 880h 的地方,而 880h 的数据看上去有数据长度, 图像尺寸的信息,一直到 8a2h 的数据开始。

到目前为止我们都是用猜的,那么猜得对不对,看看 0221BEC0 的第二组数据好了,第二组数据的起始位置在 039880h

看上去我们似乎猜对了,我们可以验证一下,从 398E2h,我们能不能提取出第二张事件图的像素数据:

看来是没有问题。

总结

像素这部分我们是可以开始写程序了,不过我们还没有拿到调色板。我们先总结下已知的文件结构:

  • PAF 文件和之前一样,也是一个图像的合集
  • 文件头部 20h~23h 记录了图像索引(注意,不是数据)的起始位置
  • 文件头部 0ch~0fh 记录了图像索引的个数

  • 图像索引长度固定为 40h
  • 图像索引偏移 14h~17h 记录了图像数据的位置

  • 图像数据偏移 10h~13h 记录了图像头位置
  • 图像头包含了图像的大小和长宽,再偏移 23h,即为图像数据的开始