Tutorial *44*

Well, I decided that it was so easy to integrate in the first place, I may as well share the love. Here's a tutorial for how to integrate my mouse-driven window/control based GUI in to Q2!

First, you'll need the UIX code package. UIX is a LGPL'ed desktop-style window/mouse driven GUI I came up with. It's totally modular, and once the UI code is integrated, the engine will function without UIX, but it won't allow you to use the menus. The downloadable version even works in software mode! Unfortunately, it doesn't appear to work in windowed mode, so until I can find the cause of that problem, it'll have to stay unsolved.

UIX can be downloaded at http://www.planetquake.com/qxx/

Now then, on with the tutorial...

Open cl_main.c and in CL_Init, replace the line:



M_Init ();

with this:



UI_Init ();

Open cl_scrn.c and in SCR_UpdateScreen, there are two lines reading:



M_Draw ();

Replace them both with:



UI_Draw ();

Open console.c, and in Con_ToggleConsole_f, replace this block:



if (cls.key_dest == key_console)

{

     M_ForceMenuOff ();

     Cvar_Set ("paused", "0");

}

else

{

     M_ForceMenuOff ();

     cls.key_dest = key_console;



     if (Cvar_VariableValue ("maxclients") == 1

         && Com_ServerState ())

         Cvar_Set ("paused", "1");

}

With this:



if (cls.key_dest == key_console)

{

     cls.key_dest = key_game;

     Key_ClearStates ();

     Cvar_Set ("paused", "0");

}

else

{

     Key_ClearStates ();

     cls.key_dest = key_console;



     if (Cvar_VariableValue ("maxclients") == 1

         && Com_ServerState ())

         Cvar_Set ("paused", "1");

}

Then, search for the line:



M_ForceMenuOff ();

and comment it out.

Open keys.c and in Key_Event, replace this code block:



case key_menu:

     M_Keydown (key);

     break;

case key_game:

case key_console:

     M_Menu_Main_f ();

     break;

with this:



case key_menu:

     UI_Keydown (key);

     break;

case key_game:

case key_console:

     UI_Desktop ();

     break;

Look for a comment block that starts with:



//

// key up events only generate commands if the game key binding is

Before it, add the code:



// The UI wants mouse1 events both down and up

if (cls.key_dest == key_menu && key == K_MOUSE1)

{

     UI_MouseStatus(down);

     return;

}

Then, find the line:



M_Keydown (key);

Replace it with:



UI_Keydown (key);

Open in_win.c. Search for the line:



#define JOY_AXIS_V   5

After it, add these lines:



extern cvar_t *ui_x;

extern cvar_t *ui_y;

Then, find the line:



RECT        window_rect;

After it, add the line:



extern int uix, uiy;      // UI controls

Go to the IN_MouseMove function. Replace this:



if ( (in_strafe.state & 1) || (lookstrafe->value && mlooking ))

     cmd->sidemove += m_side->value * mouse_x;

else

     cl.viewangles[YAW] -= m_yaw->value * mouse_x;



if ( (mlooking || freelook->value) && !(in_strafe.state & 1))

{

     cl.viewangles[PITCH] += m_pitch->value * mouse_y;

}

else

{

     cmd->forwardmove -= m_forward->value * mouse_y;

}

With this:



if(cls.key_dest == key_menu)

     uix += mouse_x * ui_x->value;

else if ( (in_strafe.state & 1) || (lookstrafe->value && mlooking ))

     cmd->sidemove += m_side->value * mouse_x;

else

     cl.viewangles[YAW] -= m_yaw->value * mouse_x;



if(cls.key_dest == key_menu)

     uiy += mouse_y * ui_x->value;

else if ( (mlooking || freelook->value) && !(in_strafe.state & 1))

{

     cl.viewangles[PITCH] += m_pitch->value * mouse_y;

}

else

{

     cmd->forwardmove -= m_forward->value * mouse_y;

}

Open cl_main.c, and comment out the lines:



M_ForceMenuOff ();

and



M_AddToServerList (net_from, s);

Open vid_menu.c, and comment out the line:



M_ForceMenuOff();

And comment out the entire contents of the CancelChanges function.

Finally, open client.h, and replace this:



//

// menus

//

void M_Init (void);

void M_Keydown (int key);

void M_Draw (void);

void M_Menu_Main_f (void);

void M_ForceMenuOff (void);

void M_AddToServerList (netadr_t adr, char *info);

with this:



//

// ui.c

//

void UI_Init();

void UI_Draw();

void UI_Keydown(int key);

void UI_Desktop();

void UI_MouseStatus(qboolean down);

extern int uix, uiy;

Now, put ui.c and uix.h in the "client" folder, remove menu.c from your project and add ui.c. Drop ui.dll in the same folder as your Q2 EXE, and bam, you've got a GUI!

Unfortunately, UIX is currently only designed to handle my in-progress game, so you'll have to create the interface yourself. However, UIX's framework is pretty easy to learn. The menus.cpp file houses the current interface settings, so you can tweak them to your liking.



 
Not logged in
Sign up
Login:
Passwd: