Skip to content

Instantly share code, notes, and snippets.

@DanielGibson
Last active March 2, 2018 20:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DanielGibson/a53c74b10ddd0a1f3d6ab42909d5b7e1 to your computer and use it in GitHub Desktop.
Save DanielGibson/a53c74b10ddd0a1f3d6ab42909d5b7e1 to your computer and use it in GitHub Desktop.
Description of the .wal format as used in Daikatana
The Daikatana .wal format is similar to Quake2, but supports a palette per texture
(even if it's not always used, see below) and 9 mipmap levels instead of 4.
If you wanna check whether a .wal is in daikatana or q2 format, check whether
the first byte is == 3 (daikatana) or > 32 (ASCII ' '; then it's likely Quake2)
because in Quake2 it's the name which should start with a printable ASCII char.
Having 9 MipMap levels implies that for many textures, the last levels will be
1x1 pixels... Daikatana itself stops loading more mipmaps once the last loaded
one has a width or height of 1.
Each mipmap level has half the width and height of the previous one.
For some reason, only skins actually use the color palette of the .wal.
Otherwise, all textures in a level share the same palette; it's saved in a 8bit .bmp
file, found at textures/$PALETTE_DIR/colormap.bmp, where $PALETTE_DIR is the value
of the "palette" KV pair from worldspawn; if that is not set or the file is not
found, pics/colormap.bmp is used as fallback.
The actual image pixel of colormap.bmp are ignored, only its colormap is used.
TODO: Do all textures contain the right palette anyway? I guess in this century we
can just ignore shared palette "optimizations", so most tools could ignore colormap.bmp
Usually one texture-set is in one directory, often named like the level (or set
of levels) it belongs to, like "e1m1", and the colormap.bmp is in that directory.
See also the dktools_readme.htm from the ionradiant download (dkmapedit.zip).
Pseudo-Code of the .wal header (which is at the beginning of the file),
all ints are 32bit Little Endian:
// I based this struct on the Q2 GPL code and did Daikatana-specific changes.
typedef struct dk_miptex_s
{
char version; // NEW: should be 3
char padding[3]; // NEW this is just garbage, skip it
char name[32];
unsigned width, height; // size of mipmap level 0, found at offset offsets[0]
unsigned offsets[9]; // NEW 9 instead of 4 mip maps stored
char animname[32];
int flags;
int contents;
unsigned char palette[256*3]; // NEW: 256 RGB color values
int value;
} dk_miptex_t;
@kduske
Copy link

kduske commented Mar 1, 2018

I don't think that this structure is correct. It looks more like this is the correct structure:

typedef struct dk_miptex_s
{
	char version;
	char name[32];
	unsigned width, height;
	unsigned offsets[9];
	char animname[32];
	int flags;
	int contents;
	int value;
	char palette[768];
} dk_miptex_t;

And, most importantly, the ints are 32bit Big Endian, not Little Endian.

@kduske
Copy link

kduske commented Mar 1, 2018

Nevermind, I was confused by the compression. There actually is padding, but it's after the name:

typedef struct dk_miptex_s
{
	char version;
	char name[32];
        char padding[3];
	unsigned width, height;
	unsigned offsets[9];
	char animname[32];
	int flags;
	int contents;
	char palette[768];
	int value;
} dk_miptex_t;

And the ints are 32bit Little Endian. Sorry for the confusion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment