DT1 Format (thanks to Clannad for the original dt1 format source) 
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
ConceptsA 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# 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
# 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# 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)
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)
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