大话2的地图文件分为新地图和旧地图,分别在newscene和scene文件夹下。
新旧两种地图格式有很大的不同。
地图的相关资料首先要感谢王大理Wangdali前辈,没有他的帮助,我自己不可能解开map数据包。
此处引用wangdali对大话2旧地图数据格式的整理
Map File Old Format
Dali Wang <wdl@sina.com>
2004-05-09 起稿 @Changchun
2004-05-10 修改 @Changchun
2006-02-19 修改 @Haikou
=======================MAP HEAD===============================
4字节 XPAM(MAPX)
4字节 地图的宽度
4字节 地图的高度
4*n字节 地图单元的引索 n=地图的宽度/640*2 * 地图高度/480*2
4字节 多出的一个地图单元引索,即结束引索,也就是文件的大小。
4字节 HGPJ (JPGH)
4字节 JPG头的大小
n字节 数据内容 n=JPG头的大小,不包括前面8字节。
==============================================================
4字节 地图单元引索的开始位置,也是KSAM的数量。
4字节 GAMI (IMAG)
4字节 大小(153600),正好是320x240x2。
n字节 数据,不包括前面8字节。
4字节 GEPJ (JPEG)
4字节 JPEG单元大小,不包括这8字节。
2字节 单元地图的宽度
2字节 单元地图的高度
n字节 地图数据
4字节 KSAM (MASK)
4字节 大小(不定)
n字节 数据,不包括前面8字节。
:
4字节 KSAM (MASK)
4字节 大小(不定)
n字节 数据,不包括前面8字节。
4字节 KOLB (BLOK)
4字节 大小(9600)
n字节 数据,不包括前面8字节。
4字节 LLEC (CELL)
4字节 大小(192)
n字节 数据,不包括前面8字节。
4字节 GIRB (BRIG)
4字节 大小(不定)
n字节 数据,不包括前面8字节。
8字节 结束单元。
==============================================================
XPAM (MAPX) 地图文件头
Index 图象单元引索
HGPJ (JPGH) 图象JPEG Head
GAMI (IMAG) 只有1028.map地图含有这个单元。
GEPJ (JPEG) 图象数据
KSAM (MASK)
:
KSAM (MASK)
KOLB (BLOK) 遮掩规则,一比特代表一个地图像素。
LLEC (CELL) 地图规则,一字节代表一个游戏坐标。
GIRB (BRIG) 光亮规则
:
:
:
GAMI (IMAG) 只有1028.map地图含有这个单元。
GEPJ (JPEG) 图象数据
KSAM (MASK)
:
KSAM (MASK)
KOLB (BLOK) 遮掩规则,一比特代表一个地图像素。
LLEC (CELL) 地图规则,一字节代表一个游戏坐标。
GIRB (BRIG) 光亮规则
***********************************************************************
旧地图
网上的现有程序大多只能解析出新地图,是因为云风对旧地图的JPEG数据进行了特殊的处理,普通的JPEG DECODER无法解析。
在解析旧地图时,需要首先提取出JPEG HEAD,然后分别和各单元的JPEG BODY结合。
在旧地图中,JPEG在解析每一个MCU前,需要提前读取YCbCr的DC数据,而不是像普通的JPEG文件那样,继承上个MCU单元的处理后的DC值,云风把每个MCU的所需的DC值,提取到了MCU数据之前,因此在普通JPEG DECODER看来,本该是下一个MCU数据的起始位置的地方,多了7字节的数据(包含3个DC值和一个bit坐标),也因此导致普通的JPEG DECODER无法解析旧地图的JPEG。
云风的JPEG文档
for (i=0;i<VDU;i+=16) {
jpeg_stream+=(jpeg_bit+7)/8;
jpeg_DC[0]=*jpeg_stream_short++; // 关键
jpeg_DC[1]=*jpeg_stream_short++; // 关键
jpeg_DC[2]=*jpeg_stream_short++; // 关键
jpeg_bit=*jpeg_stream++; // 关键 一字节bit坐标
for (j=0;j<HDU;j+=16) {
if (*(jpeg_stream+(jpeg_bit+7)/8)==0xff) {
jpeg_stream+=(jpeg_bit+7)/8;
jpeg_bit=0;
while (*jpeg_stream!=0xff) ++jpeg_stream;
++jpeg_stream;
jpeg_DC[0]=jpeg_DC[1]=jpeg_DC[2]=0;
}
jpeg_decode_DU(jpeg_ybuf,0);
jpeg_decode_DU(jpeg_ybuf+64,0);
jpeg_decode_DU(jpeg_ybuf+128,0);
jpeg_decode_DU(jpeg_ybuf+192,0);
jpeg_decode_DU(jpeg_cbbuf,1);
jpeg_decode_DU(jpeg_crbuf,2);
YCbCr411((unsigned short*)(output_buffer+i*pitch)+j,pitch);
}
}
把这段程序移植到云风的JPEG Decoder上,就可以解析了旧地图的JPEG了。