-
-
Notifications
You must be signed in to change notification settings - Fork 19
GUI File Format
GUI files define the components and layout of a screen or menu. For example, the main menu screen, in-game unit orders panel, and many other panels and dialogs are all defined using GUI files.
Each gui file represents a particular screen or panel. It can be the full screen or just a small part of it. We'll call a gui file as a whole an interface.
Each interface is made up of a collection of elements called gadgets. A gadget is analogous to a widget or control in other frameworks. It can be anything from a button to a scroll bar.
Here's an example of a simple gui file containing two gadgets:
[GADGET0]
{
[COMMON]
{
id=0;
assoc=205;
name=Mainmenu.GUI;
xpos=0;
ypos=0;
width=640;
height=480;
attribs=52685;
colorf=52685;
colorb=52685;
texturenumber=0;
fontnumber=-51;
active=1;
commonattribs=-51;
help=;
}
totalgadgets=6;
[VERSION]
{
major=-51;
minor=-51;
revision=-51;
}
panel=;
crdefault=;
escdefault=;
defaultfocus=SINGLE;
}
[GADGET1]
{
[COMMON]
{
id=1;
assoc=126;
name=SINGLE;
xpos=139;
ypos=393;
width=96;
height=20;
attribs=2;
colorf=0;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=54;
help=;
}
status=0;
text=SINGLE;
quickkey=83;
grayedout=0;
stages=0;
}
The first gadget in the list is special and refers to the interface itself. It defines the interface's position on the screen, its size, background image etc. All gadgets after the first represent an element contained within the interface.
Each gadget has a set of common properties, defined under the COMMON key,
and a set of gadget-specific properties,
defined at the top level of the gadget.
Common properties are properties that are common to all types of gadget. This means that each gadget has all of these properties. However, some types of gadget may ignore some common properties.
Gadget-specific properties are properties that are unique to that type of gadget.
Defines the type of the gadget, i.e. what the gadget is.
| value | meaning |
|---|---|
| 0 | Unknown/Invalid |
| 1 | Button |
| 2 | List Box |
| 3 | Text Field |
| 4 | Scroll Bar |
| 5 | Text Label |
| 6 | Surface |
| 7 | Font Definition |
| 12 | Picture Box |
In Cavedog-authored GUI files, the first gadget in the file (which represents the interface itself) always has ID 0.
A Surface represents an area that will be filled with a picture at runtime. For example, it's used to display the minimap on the map selection dialog, or a screenshot of your saved game on the load game dialog.
Most of these gadget types need other optional fields or have extra possibilities. We'll discuss that later in this text.
The name is used for two things:
- the graphic used for the gadget
- as a target for "events" that are hard-coded into the engine
To find the graphic for the gadget, TA looks for a GAF file with the same name as the menu file and looks inside it for an entry matching the name of the gadget. If this file is missing or there is no matching entry, TA looks for the entry in commongui.gaf instead. If no matching entry is found, TA may attempt to pick an appropriate default based on other properties of the gadget. For example, there are default fallbacks for buttons based on their size. This is why the buttons in MAINMENU.GUI, which represent the main menu that appear when you open TA, use a button graphic even though there's no corresponding entry in the gaf file.
For a button to actually do something, it has to be linked to an event that's often hard coded. In MAINMENU.GUI you can see several button gadgets, one named INTRO, Credits, MULTI, SINGLE and EXIT. These 5 words are hard-coded variable names for this menu. You cannot have one from another menu. So you can't really add functionality to a menu, just substract some by not using them.
There's a lot of hard-coded events, pretty much a completely different new set for each menus. The only way to know them, is to look at Cavedog original GUI files and deduce them from the buttons in it.
A button with a name that isn't linked to an event will be pressable but it wont have any impact on the game.
The event HELPTEXT appears to work in every GUI. When used as the name for a label, the label will display info about the gadget your cursor is on. It seems that the info is hard-coded sadly, so you can't add new ones. This has not been well-researched, so if anyone discovers new information please update this section.
Defines the width and height of the gadget. However, it's ignored by some gadgets.
Defines the x and y coordinates of the gadget.
For the first gadget, if the x, y coordinates would mean that the interface goes off the screen, the coordinates will be overridden so that the interface fits completely within the screen. This is why, in MAINMENU.gui, you need to reduce the interface width and height to something smaller than 640x480 before you move it around.
If 1, then the gadget will be visible, if 0 then it's invisible.
I found ONE use for this but I'm sure I'm missing something. When you set a custom font, it sets all the labels to this font. Well if you set fontnumber to something different than 0, then it will use the default TA font again.
Stores various flags for the gadget.
Attribs appears to be a bitfield that can combine multiple flags. The effect of each flag depends on the type of the gadget. The following flags have been discovered so far:
The following attributes apply to non-staged buttons. That is, buttons that either don't have a "stages" property or have "stages" set to 0.
| Value | Meaning |
|---|---|
| 1 | Display text label, aligned left |
| 2 | Display text label, aligned center |
| 16 | Behave as a radio button |
| 64 | Behave as a toggle button |
| 256 | Behave as a cycling button |
By default, buttons do not display a label. Either flag 1 or 2 must be set for a label to appear. Staged buttons ignore flag 1 and 2 and always display a label, aligned left.
When behaving as a radio button, the button emits its event when the mouse is pressed down. The button remains pressed down until another button in the same "assoc" group is pressed. If the button is clicked while already pressed down, it emits its event again and remains pressed down.
When behaving as a toggle button, the button emits its event when the mouse is released. The button remains pressed down until another button in the same "assoc" group is pressed or the button is clicked again. If the button is clicked while already pressed down, it emits its event again and becomes unpressed.
When behaving as a cycling button, the button emits its event when the mouse is pressed down. The button immediately cycles to the next image in the sequence without displaying a "pressed" image. Repeatedly clicking the button will cycle it through the images in its animation sequence. This behavior is similar to, but subtly different from, a staged button.
Flags that relate to the same thing seem to be mutually exclusive. When both flags 1 and 2 are both set, flag 1 takes precedence. When flags 16 and 64 are both set, flag 16 takes precedence (flag 256 untested).
| Value | Meaning |
|---|---|
| 1 | Behave as a horizontal scroll bar |
| 2 | Behave as a vertical scroll bar |
Associates gadgets together into a group. Gadgets will receive messages from other gadgets in the same group which they may react to in some way. The following interactions have been discovered.
-
If a scrollbar and a listbox are in the same group, they will synchronize their scroll positions. When the listbox is scrolled the scrollbar knob will change position, and when the scrollbar buttons are pressed the listbox will scroll. If a scrollbar is in the same group as another scrollbar they will also become synchronized.
-
A button that is set to behave as a radio button will become unpressed whenever another button in the same group is pressed down.
Appears to do nothing.
Appears to do nothing.
Appears to do nothing.
I'll describe these tags with the gadget they're used with, it'll simplify things greatly, since many have to be used in conjunction with each others.
Many of these tags have default value of 0 or an empty text but in game, the value isn't 0 or the text is different. This is because for gadgets having Event name for the current interface, TA do some special checks or in this case it modify some variables value.
One last thing, some gadget are invisible in game but you KNOW they're there and they should be visible. Things like buttons or labels. This is because TA checks for gadgets with some specific Event name and make them invisible under some circumstances.
The header is the first gadget in an interface that I spoke of earlier. The special tags are :
This is used to indicate the total number of gadgets in the interface but it's a bogus tag. It doesn't have any effect on the interface, that I can see.
This is used to set the background picture of the interface. If the interface already uses a PCX-based background, then leave it blank.
Setting the gaf works a bit like the name tag, it refers to the name of a sequence in a gaf file with the same name as the gui file or a sequence in commongui.gaf.
The name of the button that will be pressed when RETURN is pressed.
The name of the button that will be pressed when Escape is pressed.
The name of the button that will have focus on by default when the interface opens. (The focus is represented by the glowing rectangle)
This bit has to be added, after the common section. Put whatever value you want to, for the major, minor and revision. It doesn't matter.
[VERSION]
{
major=-51;
minor=-51;
revision=-51;
}
[GADGET0]
{
[COMMON]
{
id=0;
assoc=205;
name=Mainmenu.GUI;
xpos=0;
ypos=0;
width=640;
height=480;
attribs=52685;
colorf=52685;
colorb=52685;
texturenumber=0;
fontnumber=-51;
active=1;
commonattribs=-51;
help=;
}
totalgadgets=6;
[VERSION]
{
major=100;
minor=-51;
revision=-51;
}
panel=;
crdefault=MULTI;
escdefault=IGPATCH;
defaultfocus=SINGLE;
}
In addition to the button-specific properties listed here, the common property "attribs" has a significant effect on the appearance and behavior of the button. Refer to the documentation of the "attribs" property for more info.
For simple buttons, this dictates which frame of the sequence in the GAF file the button will start on. If you go past the max number of frames in the sequence, the button will be invisible.
For multiple stages buttons, the status has to be 0 or you'll get the wrong frame.
The number of stages a button has.
A setting of 0 means that the button does not have stages and is the same as omitting the property entirely.
A setting of 1 actually means that the button has two stages, an "off" stage and an "on" stage. The behavior is equivalent to a setting of 2, but the TA game data supplies a different set of button images that are more suited for an on/off toggle button.
A setting of 2 or more means that the button has that many stages. These stages are all "on" stages, in contrast to the behavior when set to 1. TA supplies default button sprites for up to 4 stages.
This is just the text of the button, type whatever you want to. For simple buttons, you just type your text, however, for multiple stages button, you have to use pipes to separate the text of each stages of the button. Here is an example for a 3-stage button:
text=Continues|Ends|Deathmatch;
This is a shortcut key that you can set for the gadget. The key is an ASCII character code.
Tells if the button is grayed out not. It makes the button disabled but visible, unlike setting active to 0.
[GADGET4]
{
[COMMON]
{
id=1;
assoc=126;
name=INTRO;
xpos=409;
ypos=393;
width=96;
height=20;
attribs=2;
colorf=0;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=54;
help=;
}
status=0;
text=INTRO;
quickkey=73;
grayedout=0;
stages=0;
}
[GADGET6]
{
[COMMON]
{
id=1;
assoc=0;
name=ARMPREV;
xpos=100;
ypos=283;
width=300;
height=40;
attribs=32;
colorf=240;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=0;
help=;
}
status=0;
text=On|Off;
quickkey=O;
stages=2;
}
Note that the text is aligned in the middle for simple buttons and it's aligned to the right for multiple stages buttons.
No gadget-specific properties.
[GADGET1]
{
[COMMON]
{
id=2;
assoc=1;
name=GAMES;
xpos=10;
ypos=10;
width=242;
height=176;
attribs=1;
colorf=15;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=54;
help=;
}
}
Pretty simple gadget, just indicate its size and position.
The maximum number of character in the textbox.
[GADGET9]
{
[COMMON]
{
id=3;
assoc=0;
name=ADDRESS;
xpos=53;
ypos=61;
width=250;
height=26;
attribs=0;
colorf=100;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=-125;
help=;
}
maxchars=30;
}
Whether it's a vertical or horizontal scrollbar is decided by the width and height. One with say a width of 16 and a height of 184 will be a vertical scrollbar, where one with a width of 184 and a height of 16 will be an horizontal scrollbar.
With the height and width, you'll get the graphic for the orientation you want but to make it fully operational, you need the right attribs value : 1 for horizontal and 2 for vertical.
This is the number of item the scroll bar contains. This isn't important, because it seems TA will always change it for scrollbar that have Event name and have an associate, beside, the result isn't visible.
Doesn't seem to affect anything.
I assume it's a position within the range of the number in the "range" tag. Sadly, you cant pre set it, it doesnt do anything.
This, is obviously the size of the know on the scrollbar. This too is usually changed by TA when the scrollbar has an associate.
[GADGET1]
{
[COMMON]
{
id=4;
assoc=243;
name=KNOB;
xpos=17;
ypos=30;
width=13;
height=150;
attribs=2;
colorf=4;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=0;
}
range=151;
thick=50;
knobpos=0;
knobsize=10;
}
[GADGET4]
{
[COMMON]
{
id=4;
assoc=243;
name=SLIDER;
xpos=317;
ypos=63;
width=150;
height=13;
attribs=1;
colorf=4;
colorb=0;
texturenumber=107;
fontnumber=0;
active=1;
commonattribs=10;
}
range=151;
thick=100;
knobpos=0;
knobsize=10;
}
Labels are used to display text, you can place them anywhere inside the interface and make them say whatever you want to.
This is the text that the label will display on the screen. Like scrollbar, if the label name is an even name, then the text you picked might get changed by TA at run time.
This is used to link a label to a button. What will happen is that when you click on the label instead of the button, it'll act just as if you clicked on the button. To make it work, just give the name of the target button as the link value.
[GADGET3]
{
[COMMON]
{
id=5;
assoc=243;
name=TEXT;
xpos=476;
ypos=132;
width=117;
height=13;
attribs=17;
colorf=0;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=0;
help=;
}
text=Location;
link=StartLocation;
}
As I mentioned earlier, blank surfaces, are dynamic picture box. They're used in TA mainly to display the Mini map, as a preview when you're selecting a map, to show the screenshot of the minimap of your saved games etc. Just make sure it has the right event name so that TA can fill it with a nice picture.. Ooooooooooh a map. (I'm tired I think ^_^;)
This is used to enable the selection rectangle visible on button and such to be visible on the Blank Surface. If hotornot = 1 then it's visible, if it's equal to 0 then the focus rectangle is invisible.
[GADGET2]
{
[COMMON]
{
id=6;
assoc=0;
name=MAPPIC;
xpos=328;
ypos=78;
width=252;
height=252;
attribs=0;
colorf=15;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=0;
help=;
}
hotornot=0;
}
This sets the default font for labels for the whole interface. Sadly, I haven't been able to change the font color or size yet, so you're stuck with black colored fonts.
This is the name of the font you want to use, check the fonts directory to know the names of the font. It's very important that you only use the name of the font in filename and not include the extension. So, for example, the files SMLFONT.FNT becomes filename=SMLFONT; .
[GADGET1]
{
[COMMON]
{
id=7;
assoc=243;
name=FONT2;
xpos=600;
ypos=321;
width=26;
height=66;
attribs=13;
colorf=15;
colorb=0;
texturenumber=100;
fontnumber=9;
active=1;
commonattribs=-125;
help=;
}
filename=SMLFONT;
}
This allow you to display a picture of a GAF sequence. As usual, the name correspond to the sequence in the gaf file that you want the picture to display.
[GADGET13]
{
[COMMON]
{
id=12;
assoc=0;
name=IGPATCH;
xpos=0;
ypos=0;
width=300;
height=40;
attribs=2;
colorf=15;
colorb=0;
texturenumber=0;
fontnumber=0;
active=1;
commonattribs=86;
help=;
}
}
The content of this page is originally based on the GUI format description written by Dark Rain. You can find a copy of the original here: