Diablo II 的DC6图像文件格式

Diablo II 的DC6图像文件格式

 

 

 

经过n天的细心研究,并且参考了一些E文资料和源程序。终于……(^_^哈哈哈哈哈哈哈,我真是天才啊!接下来就是一阵鸡飞蛋打!惨!)。算了,还是开门见山吧!

 

 

 

简单的来说,DC6文件主要分为3部分:

1.        文件头(24字节);

2.        图像帧在DC6文件中的指针索引(大小还得由文件头的一些数据来确定);

3.        图像帧数据(包括帧头(32字节)和经过编码了的图像帧数据(大小由帧头的一个数据决定));

 

 

 

下面我们就分别来简单地了解一下DC6文件的三部分:

 

 

 

一.   文件头

 

 

 

C语言原型:

typedef struct

{

   long  version;        // 06 00 00 00

   long  unknown1;       // 01 00 00 00

   long  unknown2;       // 00 00 00 00

   UBYTE termination[4]; // EE EE EE EE or CD CD CD CD

   long  directions;     // xx 00 00 00

   long  frames_per_dir; // xx 00 00 00

} DC6_HEADER_S;

 

 

 

下面是mptrlitghhth.dc6的文件头(24字节):

00000000h: 06 00 00 00 01 00 00 00 00 00 00 00 EE EE EE EE ; ............铑铑

                1.          2.          3.          4.

00000010h: 08 00 00 00 06 00 00 00                         ; ........

                5.          6.

 

 

 

这里:

1.      version  这是DC6的版本号,一般都为06 00 00 00;

2.      unknown1  未知,一般为01 00 00 00;

3.      unknown2  未知,一般为00 00 00 00;

4.      termination[4]  一般为EE EE EE EE或CD CD CD CD;

5.      direction   这是帧集合数目;

6.      frames_per_dir  每个帧集合包含的帧数

 

 

 

二.   帧指针索引

 

 

 

有了文件头的数据,我们就可以计算出图像帧指针索引表的大小了,以及这个DC6文件中有多少帧图像了。在mptrlitghhth.dc6中有8个direction(帧集合数目),而每个direction中又有6个图像帧(Frame)。那么整个mptrlitghhth.dc6中就有direction*frames_Per_frm=48帧图像。而图像帧指针索引表的大小就有48*sizeof(long)。

 

 

 

接下来就是mptrlitghhth.dc6图像帧指针索引表:

00000010h: 08 00 00 00 06 00 00 00 D8 00 00 00 EC 0F 00 00 ; ........?..?..

00000020h: F3 1E 00 00 A6 2E 00 00 A8 3E 00 00 0A 4E 00 00 ; ?..?..?...N..

00000030h: DF 5C 00 00 B6 6B 00 00 51 79 00 00 B2 86 00 00 ; 運..秌..Qy..矄..

00000040h: 79 94 00 00 DF A2 00 00 C6 B1 00 00 BE C0 00 00 ; y?.撷..票..纠..

00000050h: 49 D0 00 00 8A DF 00 00 E5 EE 00 00 FE FD 00 00 ; I?.娺..孱....

00000060h: F7 0C 01 00 8E 1B 01 00 A7 27 01 00 4B 34 01 00 ; ?..?..?..K4..

00000070h: 1B 42 01 00 9A 50 01 00 17 5F 01 00 AA 6F 01 00 ; .B..歅..._..猳..

00000080h: C4 7F 01 00 86 90 01 00 F7 A1 01 00 44 B3 01 00 ; ?..啇..鳌..D?.

00000090h: B7 C3 01 00 54 CF 01 00 4A DA 01 00 3E E6 01 00 ; 访..T?.J?.>?.

000000a0h: 2B F2 01 00 56 FD 01 00 F0 08 02 00 22 19 02 00 ; +?.V?.?.."...

000000b0h: BE 28 02 00 2D 38 02 00 DC 47 02 00 C2 57 02 00 ; ?..-8..蹽..耊..

000000c0h: 25 68 02 00 CE 73 02 00 4E 80 02 00 27 8D 02 00 ; %h..蝧..N€..'?.

000000d0h: 54 99 02 00 FD A3 02 00                         ; T?...

 

 

 

这里第一个指针D8 00 00 00指向文件mptrlitghhth.dc6中000000d8h的地方,就是第一个帧集合的第一帧图像开始的地方;同理第二个指针EC 0F 00 00就指向文件mptrlitghhth.dc6中00000fech的地方,就是第一个帧集合的第二帧图像开始的地方;紧接着就是第一个帧集合的第三帧图像的指针了,一直到第八个帧集合的第六帧图像的指针而结束。

 

 

 

三.   帧数据

 

 

 

一帧图像的数据,包括两个部分:

1)        帧头(32字节);

 

 

 

C语言原型:

typedef struct

{

   long flip;

   long width;

   long height;

   long offset_x;

   long offset_y;        // from bottom border, not up

   long unknown;

   long next_block;

   long length;

} DC6_FRAME_HEADER_S;

 

 

 

下面是第一个帧集合的第一帧图像的帧头:

000000d0h: 54 99 02 00 FD A3 02 00 00 00 00 00 31 00 00 00 ; T?.......1...

                                        1.          2.

000000e0h: A9 00 00 00 EF FF FF FF 03 00 00 00 00 00 00 00 ; ?..?........

                3.          4.          5.           6.

000000f0h: EC 0F 00 00 F1 0E 00 00                         ; ?..?..

                7.          8.

 

 

 

这里:

1.        flip  一个标志,为00 00 00 00图像是由下往上显示的,为为01 00 00 00则反之;

2.        width  这一帧图像中有用数据所在的矩形区域的宽度;

3.        height  同上;

4.        offset_x  怎么说呢?首先我们将一个帧集合的所有图像帧一张张的摆放在一定的位置,并且按照一定的顺序叠放在一起,最后我们用一颗钉子在适当的位置将这些图象帧钉起来,这样就可以使的顺序播放这些图象帧所形成的动画就不会出现偏差了。那么,我们将钉钉子的位置设为原点,向右设为x的正方向,而向下就设为y的正方向,那么这一帧图像的左下角的坐标就在这个坐标原点的(offset_x,offset_y)上。为什么这样做,是由于DC6各帧的图像尺寸大小是不一样的!

原始图像

原始图像

“钉”好了的图像

“钉”好了的图像

5.        offset_y  同上;

6.        unknown  未知;

7.        next_block  指向下一个图像帧的指针;

8.        length  这一帧图像的有用数据经过编码后的长度;

 

 

 

2)        经过编码了的图像数据;

 

 

 

首先,必须了解一下一个很重要的字节,那就是0x80。这个字符在图像数据中是作为换行符来用,也就是换行的标志。接下来,我们就从图像数据的第一个字节取得一个字节BYTE:

if BYTE = 0x80, 本行结束, 将光标移到下一行首

else

if BYTE & 0x80 (判断该字节的第7位是否是1) then 向内存写入BYTE & 0x7F (就是取BYTE的低 7位)个透明象素(这个透明象素还不知道从哪里得到啊!)。

else 读取文件中接下来的BYTE个数据,并写入内存。

 

 

 

如此反复,直至将这一帧的length个字节读取完。需要说明,如果遇到了0x80,而一行像素还未填满,就要用透明色将其填满。两帧数据之间用三个字符(EE EE EE)来分隔开。DC6的一帧图像的最大高宽是256*256。

 

 

 

最后,说明一下DiabloII的调色板,据我在一份E文资料上看到的,不同的场景下使用了不同的调色板!部分原文是这样的:

 

 

 

act1      : act 1 stuffs & inventory gfx

act2      : act 2 stuffs & inventory gfx

act3      : act 3 stuffs & inventory gfx

act4      : act 4 stuffs & inventory gfx

act5      : act 5 stuffs & inventory gfx

endgame   : ending screen (Talrasha giving you honorific title)

endgame2  : ending screen (Cain giving you honorific title)

fechar    : character creation screen

loading   : loading screen (the Wanderer in front of the Monastery doors)

menu0     : Beta screenshot # 1

menu1     : Beta screenshot # 2

menu2     : Beta screenshot # 3

menu3     : Beta screenshot # 4

menu4     : Beta screenshot # 5

sky       : game selection screen

static    : all GUI (Graphic User Interface) stuff (get some random results)

trademark : trademark screen

units     : all the GUI icons (but in has been succefully used for the

            trademark screen, game select & Gui stuff, without distorsion)

 

 

 

而具体什么DC6文件使用什么调色板,那就要看一看DiabloII的资源MPQ文件里的一些信息了!另外,DiabloII的调色板文件的是以BGR格式来储存的,而并非RGB格式。

 

 

 

^_^瞎编乱写,如有错误请与我联系。E-mail:a-rice@21cn.com      QQ:23271576

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Write java code: Copy the files, small_weapons.txt, and large_weapons.txt from the assignment folder on Blackboard and save them to your folder. For testing purposes, you should use the small file. Use the large file when you think the application works correctly. To see what is in the files use a text editor. Nilesh is currently enjoying the action RPG game Torchlight 2 which is an awesome game and totally blows Auction House Simulator 3, oh sorry, that should be Diablo 3, out of the water. He has got a file containing info on some of the unique weapons in the game. The transaction file contains the following information: Weapon Name (string) Weapon Type (string) Damage (int) Weapon Speed (double) … To tell if one weapon is better than another you need to know the Damage Per Second (DPS) the weapon does, since weapons have a different attack speed. DPS is calculated by taking the damage value and dividing it by the attack speed.a) You will write a program that will allow Nilesh to load the file and display the weapon info and DPS of every weapon in the input file. When the user chooses to open a weapon file, they are required to type in the filename. It will then read the 4 values about a particular weapon and then display the 4 values to the console window on one line neatly padded along with the DPS of the weapon. This is repeated until the end of the file. b) Modify your code from a) so that the weapon information written to the console window is also written to a text file. The user should be able to specify the name of the file. Add a header to the beginning of the file which has column headers for each column. At the end of the text file display the total number of weapons in the file. c) Document your code appropriately and add your name and id number as comments at the top of your code. Please also submit this text file you have created. Enter the file you want to search end with .txt: large_weapons.txt 1 Blackfang Bludgeon Great Hammer 489 1.44 339.58333333333337 2 Bones 2 Boneshredder Great Axe 256 0.84 304.76190476190476 3 Comet's Tail Great Sword 872 1.2 726.6666666666667 4 Decapitator Great Sword 188 1.08 174.07407407407408 5 Demolisher Great Hammer 887 1.32 671.9696969696969
05-27

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值