注册游戏账号
 
您的位置石器首页 > 石器攻略
客户端BIN
 

<<返回上一页

石器时代客户端BIN文件解析

    石器时代的客户端文件组成中Bin文件占了绝大部分的空间,我们在学习石器时代的同时,也一起来了解一下石器时代客户端的技术。

石器时代客户端BIN文件解析

一.石器图片数据


图片地址文件
CrossGate GraphicInfo*_*.bin
StoneAge Adrn_*.bin


客户端中这类文件存放了图片的地址索引,由若干个大小一样的块组成,每个块为80字节(魔力长度为40字节),格式如下:

字段类型 内容 说明
LONG 序号; 图片的编号
DWORD 地址; 指明图片在数据文件中的起始位置
DWORD 块长度; 图片数据块的大小
LONG 偏移量X; 显示图片时,横坐标偏移X
LONG 偏移量Y; 显示图片时,纵坐标偏移Y
LONG 图片宽度; ...
LONG 图片高度; ...
BYTE 佔地面积-东; 佔地面积是物件所佔的大小,1就表示占1格
BYTE 佔地面积-南; 同上
BYTE 标志; 用于地图,0表示障碍物,1表示可以走上去
BYTE[5] 未知; 在StoneAge中本字段长度为45字节
LONG 地图编号; 低16位表示在地图文件裡的编号,高16位可能表示版本,非地图单位的此项均为0


其中XY是偏移量用于图片定位的,比如X=-18,Y=-19,如果将图片显示在(100,100),那麽实际位置应该是(82,81),这样才可以和其它图片协调,在做人物动作gif的时候必须用这个参数来调整每一帧的位置,否则动作是抖动的,做地图也需要,否则会错位。

图片数据文件
CrossGate Graphic*_*.bin
StoneAge Real_*.bin


这个文件包含了所有图片的原始数据,每个数据块由数据头+数据组成,每个数据头长度16字节,格式为:

字段类型 内容 说明
BYTE[2] 魔数; 固定为'RD'
BYTE 版本; 偶数表示未压缩,按位图存放;奇数则表示压缩过
BYTE 未知; ...
LONG 宽度; ...
LONG 高度; ...
LONG 块长度; 数据块的长度,包括数据头本身的长度(16BYTE)


后三项和地址文件中的一样,图像数据紧跟在数据头后面。
例如,要解开第100个图片,首先在GraphicInfo_*.bin裡定位到第100条记录,即偏移(40*100)字节的位置,根据读出的地址在Graphic_*.bin中找到对应的数据块,就可以读出图片数据了。
绝大部分图片数据都是压缩过的,算法后面会介绍。


二.石器动画信息


动画地址文件

 
CrossGate AnimeInfo*_*.bin
StoneAge Spradrn_*.bin


存放每个动画在动画序列文件中的地址索引,每个数据块大小12字节

字段类型 内容 说明
DWORD 序号; 动画序号
DWORD 地址; 指明在动画信息文件中的地址
WORD 动作数目; 表示该角色有多少个完整的动作(包括各个方向)
WORD 未知;  

动画信息文件
CrossGate Anime*_*.bin
StoneAge Spr_*.bin


该文件存放了全部动作的图片序列,每个动作由数据头+若干序列号组成,数据头长度12字节。

字段类型 内容 说明
WORD 方向号; 0-7分别表示8个方向
WORD 动作号; 表示该动作的含义,比如坐下或者走路
DWORD 时间; 该动作完成一遍所需时间,单位为毫秒
DWORD 帧数; 该动画有多少帧,决定后面数据的大小


某些动作号不是所有角色都有,比如跑步前的准备动作。

有多少帧,后面就跟有多少个序列号,每个序列号长10字节。

字段类型 内容 说明
DWORD 图片号; 该帧所使用的图片
CHAR[6] 未知; ...


图片号就是该帧所用的图片序号,用图片数据裡说的方法就可解出每一帧的图片数据。。

例如要解出340号角色的1方向的第5个动作,先在AnimeInfo_*.bin中定位到第340号数据块,即偏移(12*340)字节的位置,读出地址和动作数,然后根据地址在Anime_*.bin中定位到对应的位置,然后从该位置开始查找方向1动作5的序列,根据帧数读出每一帧的图片号,通过图片号解出对应的图片就行了。

其中未知的字段表示我还不知道用处的。

注意:CrossGate的动画序列地址文件AnimeInfo_*.bin,可能由于开发时的某些原因,造成存放了3遍序列,并且按前两遍解出的动画是错误的,要以第3遍为准,第2375号角色才是第0号,其他的版本没有这问题。


三.石器地图格式


地图文件就是map目录下的那些,CrossGate的地图档在最前面有12个字节的文件头,内容为"MAP"(后9字节为0),StoneAge则没有文件头,其它完全一样。

地图文件
字段类型 说明
DWORD 地图长度-东(W)
DWORD 地图长度-南(H)
BYTE[W*H*2] 地面的数据,每一个单位2字节,为0表示无地面
BYTE[W*H*2] 地上的物件等,每一个物体2字节,为0表示该处无物件
BYTE[W*H*2] 地图标志,每一个单位2字节,具体不清楚,只知道对会引起地图切换的地方有标识

地图是45度视角的四边形,数据的存放顺序是从东到西,由南至北,起点为左边角(东0,南0)。
假设读入的3X3地图数据顺序为123456789,对应的地图显示:
3
2 6
1 5 9
4 8
7

这样读出来的数据是地图编号,在图片数据中说过,图片地址文件的每一条记录的最后一个字段就是地图编号,现在就是根据这个编号反查出对应的图片序号,将它显示出来,由于游戏本身没有地图索引文件(那是在运行游戏的时候生成的),所以要自制一份方便查找,这裡要注意的是地图编号并不是连贯的,比如StoneAge最大的编号为41000,实际上用到的只有1万多点,中间有很多编号是未使用的。

前面说过,每个图片都有偏移量用于对齐,画地图的时候也需要的,不过这裡有点问题,若只是将偏移量加上坐标,地面没有问题,而建筑物纵坐标则会错位,我并不知道正确的做法,我是这样处理的:
假设纵坐标偏移量为y,图片高度h,要画的坐标为y0,那麽实际的坐标y1就是
y1=y0+h-47+y
47是一个单位地面的高度(所以地面不必这样处理,因为h-47=0),这样做可以基本对齐,希望有朋友提供更标准的方法。

另外,关于缩略图,就是将每个单位(佔地面积1X1)缩成如下的四个点:

□□□
如果一个物件面积为2X1,那麽就是

□□□□
□□□
缩略图中每个图片都只用一种颜色表示,而这个颜色好像也是游戏自动生成的,所以要做缩略图的话,自己要製作一份颜色表。



四.石器压缩算法


这是JSS自定的一种Run-Length算法,用于StoneAge和CrossGate,下面是说明:

首字节(00) 01 02 03 说明
0n String     长度为n的字符串
1n m String   长度为n*0x100+m的字符串
2x y z String 长度为x*0x10000+y*0x100+z的字符串
8n X     填充n个X
9n X m   填充n*0x100+m个X
Ax X y z 填充x*0x10000+y*0x100+z个X
Cn       填充n个背景色
Dn m     填充n*0x100+m个背景色
Ex y z   填充x*0x10000+y*0x100+z个背景色


比如,C9表示填充9个背景色,D1 10表示填充0x110个背景色,12 50表示后面跟著一个长度为0x250的字符串,91 02 30则表示将0x02重複0x130遍。


五.石器调色板


StoneAge的调色板文件是位于data/pal目录下的palet_*.sap,CrossGate的则为bin/pal目录下的palet_*.cgp,每个文件长度均为708字节,每种颜色3字节,所以每个文件都包含了236种颜色,要注意的是它不是从0号颜色开始排列的,而是从16号,即16-252,但实际上是16-240,前16种颜色和后16种颜色都是指定,文件中的240-252号颜色并没有使用,下面是指定的32种颜色:

0-15号色
颜色号 0 1 2 3
RGB值 (00,00,00) (00,00,80) (00,80,00) (00,80,80)
颜色号 8 9 A B
RGB值 (C0,DC,C0) (F0,CA,A6) (00,00,DE) (00,5F,FF)
颜色号 4 5 6 7
RGB值 (80,00,00) (80,00,80) (80,80,00) (C0,C0,C0)
颜色号 C D E F
RGB值 (A0,FF,FF) (D2,5F,00) (FF,D2,50) (28,E1,28)
240-255号色
颜色号 F0 F1 F2 F3
RGB值 (96,C3,F5) (5F,A0,1E) (46,7D,C3) (1E,55,9B)
颜色号 F8 F9 FA FB
RGB值 (80,80,80) (00,00,FF) (00,FF,00) (00,FF,FF)
颜色号 F4 F5 F6 F7
RGB值 (37,41,46) (1E,23,28) (F0,FB,FF) (A5,6E,3A)
颜色号 FC FD FE FF
RGB值 (FF,00,00) (FF,80,FF) (FF,FF,00) (FF,FF,FF)


说一下常用的几个调色板:

  白天 傍晚 黑夜 凌晨
StoneAge palet_01.sap palet_02.sap palet_03.sap palet_04.sap
CrossGate palet_00.cgp palet_01.cgp palet_02.cgp palet_03.cgp



六.各版本对应的文件


CrossGate每个大版本都有相对独立的文件,比如最初的版本图片数据文件是Graphic_*.bin等,而龙沙的则是GraphicEx_*.bin,附加上了"Ex",下面是各个版本所使用的附加名。

版本 附加名
龙之沙时计 Ex
乐园之卵(精灵) V3
乐园之卵 _PUK2



七.后续版本的改动


这裡说的是CrossGatePuk2(乐园之卵)的数据格式变动。
乐园之卵中的图片不再使用全局调色板,静态图片都自带调色板,动画则是用隐藏调色板。

首先是自带调色板,图片数据中的文件头被扩充至20字节,且版本字段大于等于2(之前的为0和1)。

字段类型 内容 说明
BYTE[2] 魔数; 固定为'RD'
BYTE 版本; 偶数表示未压缩,按位图存放;奇数则表示压缩过
BYTE 未知; ...
LONG 宽度; ...
LONG 高度; ...
LONG 块长度; 数据块的长度,包括数据头本身的长度(20BYTE)
LONG 调色板长度; 调色板数据所佔的长度,通常为0x300,即256*3=768


还原后的数据最后那部分则是自带的调色板数据,大小和调色板长度字段的内容相同。

隐藏调色板本身其实是一些4X1的自带调色板的图片,它们的地图编号字段被重新解释了,表示使用这个调色板的动画序号,比如地图编号为0x1B680,那麽在还原第0x1B680号动画的时候,就要使用该图片所带的调色板。
隐藏调色板存在于GraphicInfoV3_*.bin中,即使是AnimeInfo_PUK2_*.bin中的动画也是使用这裡的调色板,从3840幅图片开始是隐藏调色板,不过并不是全部连续存在的,所以需要判断,除了宽4高1外,普通图片的地图编号高位为0或者3(乐园版本的地图),调色板的则不是,可以依此辨别。

乐园之卵的动画也有很大改变,同一类型的各种宠物,以前是各自有独立的图片,现在是通过改变调色板来区别的(我认为如果能将玩家角色这样简化就好了,宠物反而不应这样),方向也简化了,右边的三个方向是左边对称过去的,这是一种偷工减料,不过也减少了文件的体积……同时也导致了数据格式的改变。动画信息文件中的数据头结构变化:

字段类型 内容 说明
WORD 方向号; 0-7分别表示8个方向
WORD 动作号; 表示该动作的含义,比如坐下或者走路
DWORD 时间; 该动作完成一遍所需时间,单位为毫秒
DWORD 帧数; 该动画有多少帧,决定后面数据的大小
WORD 调色板号; 没完全弄清楚,我不用它来判断
WORD 反向; 若为奇数表示该序列的图片左右反向
DWORD 未知; 为0xFFFFFFFF,可能是结束符,便于以后再扩充?

本文也分析了CrossGate的文件格式,因为StoneAge(石器时代)和它差不多(最初均为同一小组作品),所以一併介绍。
作者:梦见草,整理:野风信子。

<<返回上一页

 
  石器我们的时代,谁也不要离开它,在这最好的网络时代!