COF, D2, DC6, DS1, DT1, TBL File format

This would be the forum for questions about how to work with mod making tools which can be a problem of its own.

Moderator: Paul Siramy

Locked
User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
Contact:
France

Hand-picked

COF, D2, DC6, DS1, DT1, TBL File format

Post by Paul Siramy » Fri Jun 07, 2002 9:54 pm

Starting from now, I'll try to make my in-progress documentations about miscelaneous file format here, to have some kind of reference, until they become good to give to the "Phrozen Keep Ressources". I'll try to make 1 post for each format too. In order to keep it "clean" I'll lock the topic, but this can be debated.

Since the posts are long, I have made this links if you want to use them :
DT1 Format 7 June 2002
DS1 Format 16 June 2002
COF and D2 Formats
TBL Format 13 november 2003
DC6 Format 8 january 2004
Last edited by Paul Siramy on Thu Jun 24, 2004 1:31 am, edited 33 times in total.

User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
Contact:
France

Hand-picked

DT1 Format

Post by Paul Siramy » Fri Jun 07, 2002 9:55 pm

DT1 Format (thanks to Clannad for the original dt1 format source)



:arrow: This doc has been completly rewrite, and is now available here : http://paul.siramy.free.fr/_divers/dt1_doc/, or you can take the ZIP version (http://paul.siramy.free.fr/_divers/dt1_doc.zip, 192 KB). It is also in the knownledge base : Knowledge Base->File Formats->The DT1 Format, but as of 26 june 2010, it lacks screenshots : they must have been lost during a web migration.




Structure of a dt1
  • * file header
    * X block headers
    * X sub-block struct, each one structured like that :
    • - Y sub-blocks header
      - Y sub-blocks data


Concepts
A block is a tile (160 pixels width max, variable height)
A tile can be understand as a floor with / without wall
The game use 3d-isometric tiles
A tile is composed of many sub-tiles
  • * Floor have 5*5 (25) sub-tiles (or less)
    • - Sub-tiles are in 3d-isometric shape
    * Walls have variable amount of sub-tiles
    • - Each sub-tiles fit in a 32*32 pixels box
Roof exists : they are floors *above* regular floors
(important for player/tile drawing priority)



File Header

Code: Select all

# bytes name            description
------- --------------- --------------------------------------------
4       x1              version (= 7)
4       x2              version (= 6)
260     zeros1          unused
4       nb_block        # of blocks
4       bh_ptr          pointer in file to block headers (= 0x114)

There are some dt1 with x1 and x2 not equal to 7 and 6. They are in
another format, or maybe just in a variation of this format, which
is not yet known.




Block Header

Code: Select all

 
# bytes name            description
------- --------------- --------------------------------------------------------
4       direction       direction
2       roof_y          # of pixels to the up when drawing the block
1       sound           sound index when walking / runing
1       animated        set to 0x01 when floor is animated
4       size_y          power of 32 pixels
4       size_x          power of 32 pixels
4       zeros1          unused
4       orientation     orientation (islveo's corner prop 1)
4       main_index      main index
4       sub_index       sub-index
4       frame           if floor animated, # of frame else ?
1       unknown_a       ?
1       unknown_b       ?
1       unknown_c       ?
1       unknown_d       ?
25      floor_flags     for each sub-tiles from right to left, then bottom to up
7       zeros2          unused
4       data_ptr        pointer to sub-block headers
4       length          length of the sub-blocks
4       sub_block       number of sub-blocks
12      zeros3          unused
What identified a dt1 in the ds1 (d2's map) is a not a simple index, it's a
combination of orientation / main_index / sub_index. There can be more than
1 tile with this combination in the dt1. In this case, the game choose 1
randomly whithin the same.

direction seems to be a "general orientation", and orientation some kind
of a part of this one. When direction is 3, there IS always 2 kind of tiles,
1 with orientation = 3, and another with 4. These 3 and 4 must be draw at
the same place, they are the left and right part of a corner.

roof_y tells in how many pixels the tile must be draw upper.

size_y and size_x are the "box" where the tile can fit in. Relative to the
bottom-left corner of the bitmap.

if floor is animated, frame is the number of frame in the animation. But it
is also used in other case... I think this is some kind of "rarity" for the
tiles with the same orientation / main_index / sub_index.

floor_flags are for each sub-tiles of the floor, even if there is only a
wall to draw. It is used to know if the player can go thru the sub-tile, but
maybe for some kind of transparency too.

Floors and roof (orientation = 0 and 15) need to be draw 80 pixels lower than
the walls.




Sub-Block Header

Code: Select all

# bytes name            description
------- --------------- ---------------------------------------------------------
2       x_pos           x offset where to raw the sub-tile
2       y_pos           y offset where to draw the sub-tile
2       zeros1          unused
1       grid_x          if sub-tile of floor, its x position in the floor
1       grid_y          if sub-tile of floor, its y position in the floor
2       tile_format     method of drawing the sub-tile
4       sub-length      length of the sub-block data
2       zeros2          unused
4       data_offset     pointer FROM SUB-BLOCK HEADER of this datas
if tile_format = 0x0001 it is a 3d-isometric sub-tile, else regular one

sample of code for drawing 3d-isometric sub-tile (in C language)

Code: Select all

void draw_sub_tile_isometric (BITMAP * dst, int x0, int y0, const UBYTE * data, int length)
{
   UBYTE * ptr = data;
   int   x, y=0, n,
         xjump[15] = {14, 12, 10, 8, 6, 4, 2, 0, 2, 4, 6, 8, 10, 12, 14},
         nbpix[15] = {4, 8, 12, 16, 20, 24, 28, 32, 28, 24, 20, 16, 12, 8, 4};

   // 3d-isometric subtile is 256 bytes, no more, no less
   if (length != 256)
      return;

   // draw
   while (length > 0)
   {
      x = xjump[y];
      n = nbpix[y];
      length -= n;
      while (n)
      {
         putpixel(dst, x0+x, y0+y, * ptr);
         ptr++;
         x++;
         n--;
      }
      y++;
   }
}
1st line : draw 4 pixels
2nd line : draw 8 pixels
3nd line : draw 12 pixles
etc...



sample of code for drawing normal sub-tile (in C language)

Code: Select all

void draw_sub_tile_normal (BITMAP * dst, int x0, int y0, const UBYTE * data, int length)
{
   UBYTE * ptr = data, b1, b2;
   int   x=0, y=0;

   // draw
   while (length > 0)
   {
      b1 = * ptr;
      b2 = * (ptr + 1);
      ptr += 2;
      length -= 2;
      if (b1 || b2)
      {
         x += b1;
         length -= b2;
         while (b2)
         {
            putpixel(dst, x0+x, y0+y, * ptr);
            ptr++;
            x++;
            b2--;
         }
      }
      else
      {
         x = 0;
         y++;
      }
   }
}
1st byte is pixels to "jump", 2nd is number of "solid" pixels, followed by the pixels.
when 1st and 2nd bytes are 0 and 0, next line.

The DT1 Tools that you can find in my signature are some prog that use this format, and their sources are provided.

13 november 2003 : update the dt1 format doc URL
Last edited by Necrolis on Thu Jan 14, 2021 11:02 am, edited 8 times in total.
Reason: fixed the KB url

User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
Contact:
France

Hand-picked

DS1 Format

Post by Paul Siramy » Fri Jun 07, 2002 9:56 pm

DS1 Format (thanks for Isilveo for the original ds1 format source)


Commented assembly listing of the ds1 loader function : ds1_load() D2Common.6FD76520 1.09b


last edit : 26 June 2010 : fixed the link, and removed the (very) old and out-of-date description
Last edited by Necrolis on Thu Jan 14, 2021 11:00 am, edited 8 times in total.
Reason: Fixed the URL

User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
Contact:
France

Hand-picked

COF and D2 Format

Post by Paul Siramy » Fri Sep 06, 2002 7:17 am

COF and D2 Format

I'll just provide some links, since I'm not in the mood to make some copy/paste :

some stats on .cof (and format)
chars_cof.d2 & cmncof_a*.cof format, & stats
stats on animdata.d2 & eanimdata.d2


Some tools I have made :
animdata_edit.zip
cofinfo.zip
d2_cof.zip

User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
Contact:
France

Hand-picked

Re: Files format (DT1, DS1, COF, D2, TBL) & win_ds1edit

Post by Paul Siramy » Fri Jun 20, 2003 11:44 am

Last edited by Paul Siramy on Thu Nov 18, 2004 8:14 pm, edited 3 times in total.

User avatar
Paul Siramy
Retired staff
Principality
Posts: 2828
Joined: Sat May 25, 2002 2:39 pm
Location: La Garenne Colombes (near Paris)
Contact:
France

Hand-picked

DC6 Format

Post by Paul Siramy » Thu Jan 08, 2004 4:45 am

DC6 Format

In short, the dc6 format is :
  • file header
  • file pointers to frame header
  • table of frame datas, each one beeing :
    • frame header
    • encoding pixels of this frame
File Header :

Code: Select all

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;
A dc6 start by 00000006 00000001 00000000
It is folowed by the termination code (EEEEEEEE ou CDCDCDCD)
Then the number of directions
Then the number of frames per directions

Mephisto is a dc6, and it has 8 directions. The total number of frames in the dc6 is of course (# of directions) * (# of frames per directions)


After this file header comes the table of pointers.
This is a table of pointers in file. In C it should be something like long frame_header_ptr[num_direction][num_frame]. Therefore a dc6 with 8 directions and 2 frames per directions will have 16 pointers.
* 1st = direction 1 frame 1
* 2nd = direction 1 frame 2
* 3rd = direction 2 frame 1
* and so on...


After the table of pointers, come a succession of Blocks. Each block is an image which have a maximum of 256*256 pixels. These blocks have a frame header, followed immediately by the encoded pixels. Note : the pixels are coded from bottom to up ! The scheme of the encoding is simple : This is even not RLE since here there's only the transparency information which is coded, the non-transparent pixels beeing a succession of RAW pixels color. To decode the pixels :
  • if BYTE = 0x80, end of line, position the cursor on the start of the line above.
  • else
    • if BYTE & 0x80 (if bit 7 is set) then write "BYTE & 0x7F" (the 7 lower bits) transparent pixels.
    • else it is a segment of RAW pixels (of max 127 pixels). Read this BYTE number of bytes and write them in the image.
Note : if the cursor reach the end of the line, we don't jump to the start of the above line : an End Of Line MUST be a 0x80 BYTE.


format of a frame header :

Code: Select all

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;
In Diablo II, usually the 'flip' is = zero, and therefore the encoding of the scanlines is from bottom to top, but if the bit is set it's from top to bottom.

width & height : sizes of this frame image, in pixels

offset_x & y : position of this frame. Used for Mephisto, or the character animation while choosing a savegame. In short : offsets are like in the DCC format.

next_block : not really used for the decoding

length : # of bytes to decode to get this frame image. These bytes are placed immediately after the frame header, this means right after the 'length' data. These bytes are followed by 3 or 4 termination bytes (check the file header).

Note : there's no palette info in the dc6, so the user must have the choice :

Code: Select all

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)
Palettes are in data\global\palette . In there, there are sub-directories. In these ones the .dat file are the palette (256 entries of BGR color), .pl2 are a collection of tons of colormaps, based on the palette.

For more details you can check the sources of these tool : And you can also check this topic : dc6 file format help
Last edited by Paul Siramy on Thu Jan 08, 2004 6:20 pm, edited 4 times in total.

Locked

Return to “Tools”