樱花大战SPR文件格式不完全分析
看到SPR后缀很容易想到sprite这个词,但分析之后才发现樱花大战的SPR文件并不是一个简单的精灵文件,倒是更像一个小型的打包格式,将跟同一sprite有关的图像啊,对齐信息啊等等都打包在一起了。鉴于SPR内容的多样性,本文仅介绍文件的整体结构以及图像部分。(http://blog.csdn.net/leexuany)
写这篇文章完全出于个人兴趣所致,至于提取工具就不发布了,van的RPGViewer2.8就可以提取樱花大战SPR的图像部分。
前16字节为文件标识 "SEGA SPRED 02.0M"
然后是N个文件索引(N一般是15,存在空的索引,数据为Big-endian)
struct spr_index {
unsigned int offset; // 子文件偏移地址
unsigned int size; // 子文件大小
unsigned int type; // 子文件类型代号(图像的代号是2)
unsigned int reserve; // 总是零
};
最后是根据索引分布的子文件数据。
举个例子,游戏中的鼠标指针(SAKURA1/SYSTEM/ICON/POINT.SPR)的内容:
Offset | 0 1 2 3 4 5 6 7 8 9 A B C D E F|
--------+------------------------------------------------+----------------
00000000|53 45 47 41 20 53 50 52 45 44 20 30 32 2E 30 4D|SEGA SPRED 02.0M
00000010|00 00 01 00 00 00 10 10 00 00 00 01 00 00 00 00|................
00000020|00 00 11 10 00 00 19 BA 00 00 00 02 00 00 00 00|................
其中第2条索引的含义就是,文件从$00001110开始,大小为$000019BA字节,类型代号为2,也就是图像数据。
SPR图像数据前10字节是图片头部,结构如下
struct spr_pic_info {
unsigned short pic_count; // 图片的总个数(Big-endian)
unsigned short var2; // 作用不明,好像总是1
unsigned short var3; // 作用不明,好像总是1
unsigned short var4; // 作用不明,好像总是0
unsigned int var5; // 作用不明,好像总是0
unsigned int var6; // 作用不明,好像总是0
};
然后pic_count个子图片信息索引
struct spr_subpic_info {
// 全部是Big-endian,不另作说明
unsigned short width;
unsigned short height;
unsigned short var2;
unsigned short var3;
unsigned int offset; // 子图片的偏移地址,从这些索引结束后开始计算。
unsigned int size;
};
图片的实际数据是压缩过的,解压缩后的数据为16位的1555格式。这里简单介绍一下压缩算法。
取第一字节,一字节含8个二进制位,可取0或1两种值。
1表示对应1字节未压缩的数据,直接复制即可;
0表示对应一个压缩过的数据串,从数据源中取2字节,假设为 YZ XU,那么就从临时缓冲中的XYZ处复制(U+3)字节。
然后依次类推。。。具体请参考解压代码。