Since there are a number of commands that can be used in the section of the menu script that provides the overall information to the program we will look at some examples of their usage. We will start by creating the script for the first menu run when the program starts, by default called the "main" menu. The minimal script required for the main menu would include the assetGlobalDef section and the menuDef section and would look like this :
#include "ui/menudef.h"
{
assetGlobalDef
{
smallFont "fonts/smallfont" 12
font "fonts/font" 16
bigFont "fonts/bigfont" 20
cursor "menu/art/3_cursor3.tga"
itemFocusSound "sound/misc/menu2.wav"
fadeClamp 1.0
fadeCycle 1
fadeAmount 0.1
}
menuDef
{
name "main"
fullScreen MENU_TRUE
}
}
The global assets section give us fading and a sound for item focus, while the menu section defines a menu named "main" that covers the entire screen. While this menu can be run without errors, it is not really usable since you have no way to exit from it. All you will have is a screen filled with the Quake 3 default shader that you can move the cursor over. Some customization is in order.
The first thing we need is a way to exit the menu. Since this is the main menu we'll add a command to allow us to exit the entire program when we want. Normally you'd have the main menu exit to a quit menu which would allow you to confirm the exit but since we are looking at simple menus right now we'll just quit the program.
menuDef
{
name "main"
fullScreen MENU_TRUE
onESC { uiScript "quit" }
}
The addition of the onESC command allows us to quit the program when the ESC key is pressed. Much better. Now for some looks. If you plan on using a background graphic for your menu then you can add that with the background command.
menuDef
{
name "main"
fullScreen MENU_TRUE
background "ui/assets/fakkback.tga"
onESC { uiScript "quit" }
}
This works fine with the default window style, WINDOW_STYLE_EMPTY, so nothing more is needed. If you want the menu to take advantage of the fading in/out defined in the global assets the you need to set the window style to WINDOW_STYLE_FILLED.
menuDef
{
name "main"
fullScreen MENU_TRUE
background "ui/assets/fakkback.tga"
style WINDOW_STYLE_FILLED
onESC { uiScript "quit" }
}
If you don't want to use a background graphic you can fill the screen with a solid color using the backcolor command. Also, you need to set the window style to WINDOW_STYLE_FILLED for this to work .
menuDef
{
name "main"
fullScreen MENU_TRUE
backcolor 1 0 0 1
style WINDOW_STYLE_FILLED
onESC { uiScript "quit" }
}
This will give a solid red background over the entire screen. Since a full screen menu will always draw a background shader you are limited to solid colors (alpha of 1) only. Otherwise the default shader will bleed thru. The same applies to using a window style of WINDOW_STYLE_GRADIENT. To get around this problem you need to create a graphic that is solid black (any size will work) and use that for the background.
menuDef
{
name "main"
fullScreen MENU_TRUE
background "ui/assets/black.tga"
backcolor 1 0 0 1
style WINDOW_STYLE_GRADIENT
onESC { uiScript "quit" }
}
Once you've figured out the menu background you may wish to put a border around it. Let's put a 10 pixel wide red border top and bottom on our menu. Borders are drawn overtop of the background graphic, if one is used..
menuDef
{
name "main"
fullScreen MENU_TRUE
background "ui/assets/fakkback.tga"
style WINDOW_STYLE_FILLED
bordersize 10
bordercolor 1 0 0 1
border WINDOW_BORDER_HORZ
onESC { uiScript "quit" }
}
Even though we at present have no menu items defined in our menu we can still define the colors we want to use when an item is disabled or when it receives the focus. Let's make the disable color a light gray and the focus color a green.
menuDef
{
name "main"
fullScreen MENU_TRUE
background "ui/assets/fakkback.tga"
style WINDOW_STYLE_FILLED
bordersize 10
bordercolor 1 0 0 1
border WINDOW_BORDER_HORZ
focuscolor 0 1 0 1
disablecolor 0.25 0.25 0.25 1
onESC { uiScript "quit" }
}
The last thing we will look at here is the scripts run when the menu opens and closes. While we can do many things in these scripts, most of them operate on menu items and at this point we have none. Instead we will simply start some background music playing when the menu opens and stop it when it closes.
menuDef
{
name "main"
fullScreen MENU_TRUE
background "ui/assets/fakkback.tga"
style WINDOW_STYLE_FILLED
bordersize 10
bordercolor 1 0 0 1
border WINDOW_BORDER_HORZ
focuscolor 0 1 0 1
disablecolor 0.25 0.25 0.25 1
onOpen { playlooped "music/sonic1.wav" }
onClose { playlooped "" }
onESC { uiScript "quit" }
}
Later we will look at more things that can be done in the onOpen and onClose commands. Since this completes our look at the main menu script, we will next look a non-full screen menu, the Quit menu.
The Quit menu is a popup menu that appears on top of the main menu and asks you to confirm that you wish to exit the game. Since it is not the main menu you don't need a assetGlobalDef section, just the menuDef section. Like every other menu, it requires a name and a rectangle definition so we start off like this :
menuDef
{
name "quit_popup"
rect 204 122 235 235
}
This defines a menu called "quit_popup" with a menu window sized 235x235 whose upper left corner is located at (204,122). Since we want this to be a popup menu, making us have to choose to exit or not, we will add the popup command to the definition.
menuDef
{
name "quit_popup"
rect 204 122 235 235
popup
}
Another feature we might want is to close the Quit menu if we hit the ESC key. This allows a quick method of canceling the menu. We use the onESC command for that.
menuDef
{
name "quit_popup"
rect 204 122 235 235
popup
onESC { close "quit_popup" }
}
Now we are ready to add the look to the menu window. Since this is not a full screen menu, if we wish to use a background graphic we must set the window style to WINDOW_STYLE_SHADER in order for it to be displayed.
menuDef
{
name "quit_popup"
rect 204 122 235 235
popup
background "ui/assets/mainpop.tga"
style WINDOW_STYLE_SHADER
onESC { close "quit_popup" }
}
We can also use a color for the background and, since this menu is drawn over top of another menu, the color alpha can be less than 1 without problems. We use the backcolor command to set the background color and can set the window style to WINDOW_STYLE_FILLED for a uniform color or WINDOW_STYLE_GRADIENT for a gradient look to the window.
menuDef
{
name "quit_popup"
rect 204 122 235 235
popup
backcolor 1 0 0 0.5
style WINDOW_STYLE_FILLED
onESC { close "quit_popup" }
}
Borders are something else that can be added to the menu. We'll put a 5 pixel wide border all around the window but make it a darker red than the window color.
menuDef
{
name "quit_popup"
rect 204 122 235 235
popup
backcolor 1 0 0 0.5
style WINDOW_STYLE_FILLED
bordersize 5
bordercolor 0.5 0 0 1
border WINDOW_BORDER_FULL
onESC { close "quit_popup" }
}
Like any other menu, we should define the focus color and the disabled color so they are avalible when we define menu items. We'll stick with the gray (disabled) and green (focus) we used in the main menu.
menuDef
{
name "quit_popup"
rect 204 122 235 235
popup
backcolor 1 0 0 0.5
style WINDOW_STYLE_FILLED
bordersize 5
bordercolor 0.5 0 0 1
border WINDOW_BORDER_FULL
focuscolor 0 1 0 1
disablecolor 0.25 0.25 0.25 1
onESC { close "quit_popup" }
}
And lastly, we'll add scripts to run when when the menu opens and closes. In a simple menu like this there isn't much that needs to be done when the menu opens (or closes). One thought would be to stop the background music playing while this menu is active. Unfortunately, this isn't possible. Each menu can have its own background music but only the menu that starts the music can stop it. Another idea is to play a sound clip when this menu opens that tells you what it does ("So you want to quit do you?"). This can be done using the onOpen command.
menuDef
{
name "quit_popup"
rect 204 122 235 235
popup
backcolor 1 0 0 0.5
style WINDOW_STYLE_FILLED
bordersize 5
bordercolor 0.5 0 0 1
border WINDOW_BORDER_FULL
focuscolor 0 1 0 1
disablecolor 0.25 0.25 0.25 1
onOpen { play "sound/quit.wav" }
onESC { close "quit_popup" }
}
Again, we will see more uses for onOpen and onClose at a later time. The last type of menu we will examine is the non-full screen, non-popup menu. This type of menu is opened over top of another menu like the popup menu but it still allows you to access menu items in the underneath menu that are outside of the top menu's items. The Team Arena Setup menu puts this to good use. The buttons on the left of the screen are in the Setup menu and when you click one of them it opens a new menu on the right side of the screen. You have access to the items in the new menu plus you can still select the buttons in the Setup menu. We'll start off the menu with the name and window area. Generally this type of menu wouldn't use the ESC key to close (that's probably controlled by a menu item in the underneath menu) so we'll leave the onESC command out.
menuDef
{
name "control"
rect 186 0 443 426
}
Just to be different we will use a movie for the background. We define which movie we want with the cinematic command and set the window style to WINDOW_STYLE_CINEMATIC to make it play.
menuDef
{
name "control"
rect 186 0 443 426
cinematic "idlogo.roq"
style WINDOW_STYLE_CINEMATIC
}
You will notice that there is no path included in the movie name. The cinematic command looks only in the video directory for the movie you request. We will not look at setting the focus and disabled colors or the open and close scripts for this menu since they are exactly the same as in the previous examples.