Anyways I've been recoding my own version of BOTF from scratch, and I've largely deciphered the WDF format for the User Interface. This is targeted for people with coding / hex editing experience. So here goes...
WDF Technical Information
The WDFs (presumably Window Definition Files) describe the layout of the various screens and user interface elements.
To begin, there are a few fundamental types used in the WDFs: byte, integer, rectangle, filename, and font entry. I use aliases for these throughout the rest of the code. Note all structures in the code are C/C++ structs, byte packed.
These basic types are described below:
Code: Select all
/* Byte (8-bit unsigned). */
typedef uint8_t wdfByte;
/* Integer (32-bit signed). */
typedef int32_t wdfInt;
/* Boolean (32-bit signed). Has value 0 or 1. */
typedef int32_t wdfBool;
/* Filename: 13-byte space-terminated string (DOS 8.3 filename + 1 character) */
typedef char wdfFilename[13];
/* Rectangle. */
struct wdfRect {
wdfInt x, y, w, h;
};
/* Entry for font */
struct wdfFontEntry
{
// this seems to be 3 bytes and 8 ints, followed by a filename for the font
// these 3 bytes are the font color
wdfByte unknown1; // red
wdfByte unknown2; // blue
wdfByte unknown3; // green
wdfInt unknown4;
wdfInt unknown5;
wdfInt unknown6;
wdfInt unknown7;
wdfInt unknown8;
wdfInt unknown9;
wdfInt unknown10;
wdfBool UseColor; // if 1, botf will use the above color, otherwise default color
wdfFilename font;
};
Code: Select all
/* Basic properties for all objects. */
struct wdfWidget {
wdfInt typeId; /* widget type, covered below */
wdfInt instanceId; /* unique identifier for this widget, so BOTF knows what this is */
wdfRect rect; /* position/dimensions */
wdfFilename backgroundImage; /* space-terminated filename of background image, may be "none" */
};
Code: Select all
/* Type ID's for widget properties. */
enum wdfWidgetType_e
{
WDF_WINDOW = 1, // 101 bytes
WDF_PUSHBUTTON = 2, // 76 bytes
WDF_MENU = 5, // 227 bytes
WDF_SLIDER = 7, // 119 bytes
WDF_SCROLLBAR = 8, // 75 bytes
WDF_LISTBOX = 12, // 181 bytes
WDF_PICTBOX = 13, // 41 bytes
WDF_TEXTBOX = 14 // 101 bytes
};
Window:
Code: Select all
struct wdfWindow
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
/* Number of objects of each type.
* There are 15 possible widget types, but only 8 are actually used.
* numObjects[0] is total number of objects.
*/
wdfInt numObjects[16];
};
Code: Select all
struct wdfPushButton
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
wdfInt unknown; // -1
wdfByte ButtonType; // 0 for FADING GLOW, 1 for SOLID GLOW, 2 for TOGGLE
wdfBool EnableRepeat;
wdfInt RepeatRate;
wdfFilename outImage;
wdfFilename inImage;
};
Code: Select all
struct wdfMenu
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
wdfRect unknown1; //TODO
wdfFontEntry font1;
wdfFontEntry font2;
wdfFilename menuFile;
wdfFilename leftImage;
wdfFilename topImage;
wdfFilename rightImage;
wdfFilename bottomImage;
wdfFilename unknown2; //TODO
};
Code: Select all
struct wdfSlider
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
//TODO: 2 bytes, followed by 4 ints
wdfByte unknown1;
wdfByte unknown2;
wdfInt unknown3;
wdfInt unknown4;
wdfInt unknown5; // this seems to be almost same as rect.w
wdfInt unknown6;
// 4 filnames: I think these are right
wdfFilename cellOffImage;
wdfFilename cellOnImage;
wdfFilename markerOffImage;
wdfFilename markerOnImage;
//TODO 3 ints
wdfInt unknown7; // this seems to be same as rect.h
wdfInt unknown8;
wdfInt unknown9;
};
Code: Select all
struct wdfScrollBar
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
wdfInt unknown;
wdfFilename thumbOnImage;
wdfFilename thumbOffImage;
wdfInt minValue;
wdfInt maxValue;
};
Code: Select all
struct wdfListBox
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
wdfInt unknown1; // always -1?
wdfFontEntry font1;
wdfFontEntry font2;
wdfInt ColumnWidths[10];
wdfInt NumColumns;
};
Code: Select all
struct wdfPictBox
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
wdfInt unknown; // int32, always -1
};
Code: Select all
struct wdfTextBox
{
wdfInt typeId;
wdfInt instanceId;
wdfRect rect;
wdfFilename backgroundImage;
wdfRect rect2;
wdfFontEntry font;
};
Each file begins with the number 2, followed by a Window structure (typeId 1). Looking at the extended properties for wdfWindow, we see:
Code: Select all
wdfInt NumObjects[16];
Well I guess that's it. Sorry if that was a bit terse. I can provide more info / code if anyone wants.
WDF Editing Software
You can download my WDF Editor here: