梦幻西游 WSG 文件格式分析

来源:互联网 发布:在线网页qq机器人源码 编辑:程序博客网 时间:2024/04/28 21:47

梦幻西游 WSG 文件格式分析

作者:leexuany(小宝)

图1

这是梦幻西游开始的动画界面,大致分为5层

1、背景层(星星、月亮和云彩其实都是一张jpg图片,根本就不动)
2、远景层(高山、湖泊和帆船,这一层缓慢的向右移动)
3、人物层(唐僧师徒四人外加一匹白龙马,这是四个was动画,坐标是固定不动的)
4、近景层(花草树木组成的近景,向右移动,速度比远景层稍快)
5、UI层(2个Logo和几个按钮)

WSG图片文件简介

梦幻的登陆界面就是这样一个动态界面,远景层和近景层图片的width都在2000像素以上,如果简单的使用bmp或jpg图片,并以透明色和alpha融合做这段动画,无论是加载还是绘制的效率都是一个问题。

因此(又是小宝猜的)梦幻的程序设计了WSG这种图片格式。这是一种基于调色板的基本不算压缩了的图片。在WSG格式中,每一张图片被分割成16X16的小块,每一块都有自己的16色高彩调色板(32字节)以及128字节或256字节颜色数据。

下面以background3.wsg为例讲解:

图2

文件头20字节,包含
4字节标志(wind)
4字节图片宽度(width)
4字节图片高度(height)
4字节关键点X坐标(不确定)
4字节关键点Y坐标(不确定)

width*height/256字节的图片块标志,1个字节对应一个图片块。
00表示对应图片块为空,比如山与山之间的大片的空隙;
40表示对应图片块格式为32字节调色板+128字节数据;
80表示对应图片块格式为32字节调色板+256字节数据;
其他跳过。


40型图片块格式很简单,开始的32字节是高彩调色板,剩下的128对应256个像素信息,4bits/像素。若1号调色板为F81F,则启用透明色,若1号调色板为0000,则说明这是80型图片块。

80型同样有32字节高彩调色板,1号调色板总是0000,剩下的256对应256个像素信息。如果用XY表示1字节的像素信息的话,则:
X=0,Y=0时跳过此像素(相当于透明色);
X=0,Y!=0时表示普通的像素,此像素的颜色为Y号调色板的颜色;
X!=0,Y任意时表示这是需要进行alpha融合的像素,算法如下:

110F2E73  |.  83E0 0F       ||and     eax, 0F                        ;  eax就是XY中的Y,颜色号110F2E76  |.  66:8B0F       ||mov     cx, word ptr [edi]             ;  cx=alpha融合前的背景色110F2E79  |.  C1E1 10       ||shl     ecx, 10110F2E7C  |.  66:8B0C43     ||mov     cx, word ptr [ebx+eax*2]       ;  取eax对应的颜色110F2E80  |.  8BC1          ||mov     eax, ecx110F2E82  |.  C1C8 10       ||ror     eax, 10                        ;  循环右移16位110F2E85  |.  81E1 1FF8E007 ||and     ecx, 7E0F81F110F2E8B  |.  25 1FF8E007   ||and     eax, 7E0F81F110F2E90  |.  66:91         ||xchg    ax, cx110F2E92  |.  2BC1          ||sub     eax, ecx110F2E94  |.  F7E2          ||mul     edx                            ;  edx是XY中的X,alpha融合系数110F2E96  |.  C1E8 04       ||shr     eax, 4110F2E99  |.  03C1          ||add     eax, ecx110F2E9B  |.  25 1FF8E007   ||and     eax, 7E0F81F110F2EA0  |.  8BC8          ||mov     ecx, eax110F2EA2  |.  C1E8 10       ||shr     eax, 10110F2EA5  |.  66:0BC1       ||or      ax, cx110F2EA8  |.  66:8907       ||mov     word ptr [edi], ax             ;  ax就是alpha融合后的颜色



现在小宝只是简单的模拟了这段alpha融合的代码,对其中的原理还不太清楚,所以只写出一个简单的查看器,暂时先不放上来了。