Motivation

Since the first release of a working Diablo II beta I'm trying to decode the DCC file-format. Its hardly packed and very cryptic. With these site I'll try to find some help from around the world. Maybe some guys out there have some nice ass-kicking ideas how to proceed. I'll try to explain, what I've found out by now.

How does Diablo II handle animations

All character/monster/missle animations are assembled from multiple layers/frames: you'll find something like the following in your d2char.mpq/data/global/chars/am/:

folder-namemeaning
cof/layer information (more later)
hd/head frames
la/left arm frames
ra/right arm frames
lg/leg frames
sh/shield frames
tr/torso frames
s1/??? (maybe weapon/special)
s2/the same
lh/left hand frames
rh/right hand frames

Within these folders you'll find the dcc files I'm speaking about. To assemble these frames to a final image you'll need to put them together depending on the current clothing and weapons. Thats the point where the cof files enter the scene. They contain information about the order: which frame from which files enters which layer in the final image... More about the cof-files later. Take a look at the following image:

assembling

Each layer contains information from a different dcc file. On which layer it will end is fixed within the cof-files.

Some words about the cof files

I've not figured out, how it exactly works but I can tell you some outlines. If you open these files with a hex-editor (the one I prefer is ultraedit) you'll see at the beginning the last 3 chars of the participating dcc-files. Take a look at the first rows of the ama1bow.cof:

a cof file

At the first byte you'll find the number of dcc-files which take part in the final image. At adresse 0x21 you'll find the first (last 3 chars) dcc-file. Then there may follow some flags (not checked yet!!!) and then the next file. At position 0x72 the table of layer-assignments starts: You'll see that for frame 0 the contens of dcc-0 will end at layer 02, contens of dcc-1 at layer 01, etc... And that for each frame of that animation.

How is a DCC file structured

Lets now come back to the original DCC file. How it's structured:

offsetmeaning
0x0000 WORDsignature (always 74 06 - CEL files version 6 ??? )
0x0002 BYTEnumber of directions (as far as I know alwyas a power of 4 (max 32?))
0x0003 BYTEnumber of frames per direction
0x0004-0x000eI don't know yet (maybe some flags)
0x000f DWORDoffset-table entry 0
0x0013 DWORDoffset-table entry 1
...direction x offsets
offset0 BITSTREAMdirection0 data
offset1 BITSTREAMdirection1 data
...

I think most of these entries are self-explaining. The offsets are absolute refering to the beginning of the files. As you can see there are no dimension information available (at the first view) so I think they must be encoded somewhere. In the next examples I will refer to the arrow.dcc. You can extract it from d2data.mpq/data/global/missles/arrow.dcc (or download it here). I've separated some arrows from screenshots:

arrow down arrow horizontally

These are only 2 shoots 1600 % bigger than the original. It was not easy to get them 'coz Diablo stores it's screenshots as JPG's what means we loose some important color-information if we use these. Becoz' of that I've created these with a DirectX snapshooter (sorry, forgot the name and URL). I will refer to these shots later.

Some words about directions

If you have read about the dcc-format in the section above you may have encountered some words about directions (BYTE 0x02 and 0x03). The number of directions will ever be a power of 4. Check the following image:

directions
As you can see I've only identified 4 directions yet. I'm not sure about the other 4. It seems that either the bottom right or the bottom left is at index 0. If I have the starting index it will be easy to insert the others above 7. Go around clockwise and insert the following indices between the existing ones. What does that mean ? Take a look at our example: the information for the straight down arrow will be within BITSREAM 04 and the arrow pointing right will be at BITSTREAM 07. How I can be so sure ? Hehehe, check the next section, that is where the action starts...

A first look into the BITSTREAMs

Ok, now we are feeding the cracks. I hope you are knowing how Bytes are working ?! If not, check some literature. What I've done ? Well a "normal" Byte will be read as follows:

That means we have to read the Bits from right to left and the Bytes from left to right. To get a continous Bitstream I've reverted the output of the Bits from every Byte. So we will get the following with the upper example:

As you can see the high-bits are now on the right side. Now we can read a continous bitstream from left to right. With that as a tool we are able to examine the frame-bitstreams for some patterns.

To find a pattern...

With the above described method I've extracted the BITSTREAMS for the arrow-frames. The following table contains the BITSTREAM of frame 4 (down heading arrow):

00000011000010010010100000101000100100100111101011110110100000000000000000000001 00000000000000001000000000010100000001000000000000000000000000000100000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000001000000000000000000000010000110100000000001000000000000000000000 00000000000000001000100100000000110010000001000000110000000100010011000000011001 10010000000101011111000101010010010100110110100100101001001010010010100100111100 11111100111111001111100011111100111111001111110011101001011100100111110101100000

With that information it should be possible to create all needed image-data. But all we have is a bunch of bits. AND of 'coz the screenshots !!! Ok, lets put some bits (the red ones) and the screenshot together:

down again 10 10 11 1110 00 10 1010 01 00 1010 01 10 1101 00 10 0101 00 10 0101 00 10 0101 00 10 0111 10 01 1111 10 01 1111 10 01 1111 00 01 1111 10 01 1111 10 01 1111 10 01 1101 00 10 1110 01 00 1111 10 10 11 00000

As you can see I've only used the last Bits from the BITSTREAM (start at the bottom right and go left and up and compare with the big table). You see the pattern ? The Bit-pairs harmonize enough with the picture to take a second look. To be sure I've checked it with the horizontal arrow (direction index 07). Let's see if it will work:

00000000101100001010100000101010010110100011011000101101110110000000000000000000 00010000000000000000000010000010100000000100000000000000000000000000010000000000 00000000000000001000000000000000000000000000000000000000000000000000000000000000 00000000000000000001000000000001000000000001010011000000000000000000000000000000 00000000000000000000010100010000000000111001000000000011100000000011100100000000 10001101100000000011100000001000110000010001000011000000100011001000000110000100 10000001101011101101010100000000110100101010111111111110101010110000000111111111 11111110101010110101010000000000101010101010101111111110101010100000010111111111 11111111111111110101010000001001111111111111111010101011010101000000000010101010 10101010101010100000000101010100101010101010101111111110100000010101010111111111 11111111111111110101010010101001111111111111111111011111100010100100101010010101 010111111111111110000000

horizontal again
11 01 01 11 01 10 10 10 10 00 00 00 01 10 10 01 01 01 01 11  11 11 11 11 01 01 01 01 10 00 00 00 11 11 11 11 11 11 11 11  01 01 01 01 10 10 10 10 00 00 00 00 01 01 01 01 01 01 01 01  11 11 11 11 01 01 01 01 00 00 00 10 11 11 11 11 11 11 11 11  11 11 11 11 10 10 10 10 00 00 01 00 11 11 11 11 11 11 11 11  01 01 01 01 10 10 10 10 00 00 00 00 01 01 01 01 01 01 01 01  01 01 01 01 00 00 00 00 10 10 10 10 01 01 01 01 01 01 01 01  11 11 11 11 01 00 00 00 10 10 10 10 11 11 11 11 11 11 11 11  11 11 11 11 10 10 10 10 01 01 01 00 11 11 11 11 11 11 11 11  11 10 11 11 11 00 01 01 00 10 01 01 01 00 10 10 10 10 11 11 11 11 11 11 11 0000000

If you don't know, how to read this take the bottom block to the right side of the image, the block above at the left of that one before... eh, check the following scheme:

resample bits

It works too. So it seems that these bit-masks build blocks of 4 tupels. But where are the color or dimension informations ? They must be encoded somewhere within the rest of the BITSTREAM. There must also be a pointer to where the "bitmask" table starts 'coz it starts suddenly within a BYTE end ends the same way.

Conclusion

As you can see I've only found some outlines about the dcc-file-format. If you are interested in some precoded tools or more preworked stuff please mail me under TeLAMoN and I'll contact you. Please mail me too if you have some corrections and extensions about my statements. Some open questions to be answered would be:

  • are the image-informations in palettized or true-color format ?
  • where are the positioning/dimension-informations ?
  • how will multiple framed (more than one frame per direction) dcc's be handeled ?
Try out some of my ideas and let me know if they work. As soon as I have a working description I'll add the new cvDCC.dll to my CV5 tool with proper credit to all, who helped me out to understand the dcc-format.


TeLAMoN of 2XS (c) 10/04/2000