Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

ui_controls2.c (52312B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 //
     23 /*
     24 =======================================================================
     25 
     26 CONTROLS MENU
     27 
     28 =======================================================================
     29 */
     30 
     31 
     32 #include "ui_local.h"
     33 
     34 #define ART_BACK0			"menu/art/back_0"
     35 #define ART_BACK1			"menu/art/back_1"
     36 #define ART_FRAMEL			"menu/art/frame2_l"
     37 #define ART_FRAMER			"menu/art/frame1_r"
     38 
     39 
     40 typedef struct {
     41 	char	*command;
     42 	char	*label;
     43 	int		id;
     44 	int		anim;
     45 	int		defaultbind1;
     46 	int		defaultbind2;
     47 	int		bind1;
     48 	int		bind2;
     49 } bind_t;
     50 
     51 typedef struct
     52 {
     53 	char*	name;
     54 	float	defaultvalue;
     55 	float	value;	
     56 } configcvar_t;
     57 
     58 #define SAVE_NOOP		0
     59 #define SAVE_YES		1
     60 #define SAVE_NO			2
     61 #define SAVE_CANCEL		3
     62 
     63 // control sections
     64 #define C_MOVEMENT		0
     65 #define C_LOOKING		1
     66 #define C_WEAPONS		2
     67 #define C_MISC			3
     68 #define C_MAX			4
     69 
     70 #define ID_MOVEMENT		100
     71 #define ID_LOOKING		101
     72 #define ID_WEAPONS		102
     73 #define ID_MISC			103
     74 #define ID_DEFAULTS		104
     75 #define ID_BACK			105
     76 #define ID_SAVEANDEXIT	106
     77 #define ID_EXIT			107
     78 
     79 // bindable actions
     80 #define ID_SHOWSCORES	0
     81 #define ID_USEITEM		1	
     82 #define ID_SPEED		2	
     83 #define ID_FORWARD		3	
     84 #define ID_BACKPEDAL	4
     85 #define ID_MOVELEFT		5
     86 #define ID_MOVERIGHT	6
     87 #define ID_MOVEUP		7	
     88 #define ID_MOVEDOWN		8
     89 #define ID_LEFT			9	
     90 #define ID_RIGHT		10	
     91 #define ID_STRAFE		11	
     92 #define ID_LOOKUP		12	
     93 #define ID_LOOKDOWN		13
     94 #define ID_MOUSELOOK	14
     95 #define ID_CENTERVIEW	15
     96 #define ID_ZOOMVIEW		16
     97 #define ID_WEAPON1		17	
     98 #define ID_WEAPON2		18	
     99 #define ID_WEAPON3		19	
    100 #define ID_WEAPON4		20	
    101 #define ID_WEAPON5		21	
    102 #define ID_WEAPON6		22	
    103 #define ID_WEAPON7		23	
    104 #define ID_WEAPON8		24	
    105 #define ID_WEAPON9		25	
    106 #define ID_ATTACK		26
    107 #define ID_WEAPPREV		27
    108 #define ID_WEAPNEXT		28
    109 #define ID_GESTURE		29
    110 #define ID_CHAT			30
    111 #define ID_CHAT2		31
    112 #define ID_CHAT3		32
    113 #define ID_CHAT4		33
    114 
    115 // all others
    116 #define ID_FREELOOK		34
    117 #define ID_INVERTMOUSE	35
    118 #define ID_ALWAYSRUN	36
    119 #define ID_AUTOSWITCH	37
    120 #define ID_MOUSESPEED	38
    121 #define ID_JOYENABLE	39
    122 #define ID_JOYTHRESHOLD	40
    123 #define ID_SMOOTHMOUSE	41
    124 
    125 #define ANIM_IDLE		0
    126 #define ANIM_RUN		1
    127 #define ANIM_WALK		2
    128 #define ANIM_BACK		3
    129 #define ANIM_JUMP		4
    130 #define ANIM_CROUCH		5
    131 #define ANIM_STEPLEFT	6
    132 #define ANIM_STEPRIGHT	7
    133 #define ANIM_TURNLEFT	8
    134 #define ANIM_TURNRIGHT	9
    135 #define ANIM_LOOKUP		10
    136 #define ANIM_LOOKDOWN	11
    137 #define ANIM_WEAPON1	12
    138 #define ANIM_WEAPON2	13
    139 #define ANIM_WEAPON3	14
    140 #define ANIM_WEAPON4	15
    141 #define ANIM_WEAPON5	16
    142 #define ANIM_WEAPON6	17
    143 #define ANIM_WEAPON7	18
    144 #define ANIM_WEAPON8	19
    145 #define ANIM_WEAPON9	20
    146 #define ANIM_WEAPON10	21
    147 #define ANIM_ATTACK		22
    148 #define ANIM_GESTURE	23
    149 #define ANIM_DIE		24
    150 #define ANIM_CHAT		25
    151 
    152 typedef struct
    153 {
    154 	menuframework_s		menu;
    155 
    156 	menutext_s			banner;
    157 	menubitmap_s		framel;
    158 	menubitmap_s		framer;
    159 	menubitmap_s		player;
    160 
    161 	menutext_s			movement;
    162 	menutext_s			looking;
    163 	menutext_s			weapons;
    164 	menutext_s			misc;
    165 
    166 	menuaction_s		walkforward;
    167 	menuaction_s		backpedal;
    168 	menuaction_s		stepleft;
    169 	menuaction_s		stepright;
    170 	menuaction_s		moveup;
    171 	menuaction_s		movedown;
    172 	menuaction_s		turnleft;
    173 	menuaction_s		turnright;
    174 	menuaction_s		sidestep;
    175 	menuaction_s		run;
    176 	menuaction_s		machinegun;
    177 	menuaction_s		chainsaw;
    178 	menuaction_s		shotgun;
    179 	menuaction_s		grenadelauncher;
    180 	menuaction_s		rocketlauncher;
    181 	menuaction_s		lightning;
    182 	menuaction_s		railgun;
    183 	menuaction_s		plasma;
    184 	menuaction_s		bfg;
    185 	menuaction_s		attack;
    186 	menuaction_s		prevweapon;
    187 	menuaction_s		nextweapon;
    188 	menuaction_s		lookup;
    189 	menuaction_s		lookdown;
    190 	menuaction_s		mouselook;
    191 	menuradiobutton_s	freelook;
    192 	menuaction_s		centerview;
    193 	menuaction_s		zoomview;
    194 	menuaction_s		gesture;
    195 	menuradiobutton_s	invertmouse;
    196 	menuslider_s		sensitivity;
    197 	menuradiobutton_s	smoothmouse;
    198 	menuradiobutton_s	alwaysrun;
    199 	menuaction_s		showscores;
    200 	menuradiobutton_s	autoswitch;
    201 	menuaction_s		useitem;
    202 	playerInfo_t		playerinfo;
    203 	qboolean			changesmade;
    204 	menuaction_s		chat;
    205 	menuaction_s		chat2;
    206 	menuaction_s		chat3;
    207 	menuaction_s		chat4;
    208 	menuradiobutton_s	joyenable;
    209 	menuslider_s		joythreshold;
    210 	int					section;
    211 	qboolean			waitingforkey;
    212 	char				playerModel[64];
    213 	vec3_t				playerViewangles;
    214 	vec3_t				playerMoveangles;
    215 	int					playerLegs;
    216 	int					playerTorso;
    217 	int					playerWeapon;
    218 	qboolean			playerChat;
    219 
    220 	menubitmap_s		back;
    221 	menutext_s			name;
    222 } controls_t; 	
    223 
    224 static controls_t s_controls;
    225 
    226 static vec4_t controls_binding_color  = {1.00f, 0.43f, 0.00f, 1.00f}; // bk: Win32 C4305
    227 
    228 static bind_t g_bindings[] = 
    229 {
    230 	{"+scores",			"show scores",		ID_SHOWSCORES,	ANIM_IDLE,		K_TAB,			-1,		-1, -1},
    231 	{"+button2",		"use item",			ID_USEITEM,		ANIM_IDLE,		K_ENTER,		-1,		-1, -1},
    232 	{"+speed", 			"run / walk",		ID_SPEED,		ANIM_RUN,		K_SHIFT,		-1,		-1,	-1},
    233 	{"+forward", 		"walk forward",		ID_FORWARD,		ANIM_WALK,		K_UPARROW,		-1,		-1, -1},
    234 	{"+back", 			"backpedal",		ID_BACKPEDAL,	ANIM_BACK,		K_DOWNARROW,	-1,		-1, -1},
    235 	{"+moveleft", 		"step left",		ID_MOVELEFT,	ANIM_STEPLEFT,	',',			-1,		-1, -1},
    236 	{"+moveright", 		"step right",		ID_MOVERIGHT,	ANIM_STEPRIGHT,	'.',			-1,		-1, -1},
    237 	{"+moveup",			"up / jump",		ID_MOVEUP,		ANIM_JUMP,		K_SPACE,		-1,		-1, -1},
    238 	{"+movedown",		"down / crouch",	ID_MOVEDOWN,	ANIM_CROUCH,	'c',			-1,		-1, -1},
    239 	{"+left", 			"turn left",		ID_LEFT,		ANIM_TURNLEFT,	K_LEFTARROW,	-1,		-1, -1},
    240 	{"+right", 			"turn right",		ID_RIGHT,		ANIM_TURNRIGHT,	K_RIGHTARROW,	-1,		-1, -1},
    241 	{"+strafe", 		"sidestep / turn",	ID_STRAFE,		ANIM_IDLE,		K_ALT,			-1,		-1, -1},
    242 	{"+lookup", 		"look up",			ID_LOOKUP,		ANIM_LOOKUP,	K_PGDN,			-1,		-1, -1},
    243 	{"+lookdown", 		"look down",		ID_LOOKDOWN,	ANIM_LOOKDOWN,	K_DEL,			-1,		-1, -1},
    244 	{"+mlook", 			"mouse look",		ID_MOUSELOOK,	ANIM_IDLE,		'/',			-1,		-1, -1},
    245 	{"centerview", 		"center view",		ID_CENTERVIEW,	ANIM_IDLE,		K_END,			-1,		-1, -1},
    246 	{"+zoom", 			"zoom view",		ID_ZOOMVIEW,	ANIM_IDLE,		-1,				-1,		-1, -1},
    247 	{"weapon 1",		"gauntlet",			ID_WEAPON1,		ANIM_WEAPON1,	'1',			-1,		-1, -1},
    248 	{"weapon 2",		"machinegun",		ID_WEAPON2,		ANIM_WEAPON2,	'2',			-1,		-1, -1},
    249 	{"weapon 3",		"shotgun",			ID_WEAPON3,		ANIM_WEAPON3,	'3',			-1,		-1, -1},
    250 	{"weapon 4",		"grenade launcher",	ID_WEAPON4,		ANIM_WEAPON4,	'4',			-1,		-1, -1},
    251 	{"weapon 5",		"rocket launcher",	ID_WEAPON5,		ANIM_WEAPON5,	'5',			-1,		-1, -1},
    252 	{"weapon 6",		"lightning",		ID_WEAPON6,		ANIM_WEAPON6,	'6',			-1,		-1, -1},
    253 	{"weapon 7",		"railgun",			ID_WEAPON7,		ANIM_WEAPON7,	'7',			-1,		-1, -1},
    254 	{"weapon 8",		"plasma gun",		ID_WEAPON8,		ANIM_WEAPON8,	'8',			-1,		-1, -1},
    255 	{"weapon 9",		"BFG",				ID_WEAPON9,		ANIM_WEAPON9,	'9',			-1,		-1, -1},
    256 	{"+attack", 		"attack",			ID_ATTACK,		ANIM_ATTACK,	K_CTRL,			-1,		-1, -1},
    257 	{"weapprev",		"prev weapon",		ID_WEAPPREV,	ANIM_IDLE,		'[',			-1,		-1, -1},
    258 	{"weapnext", 		"next weapon",		ID_WEAPNEXT,	ANIM_IDLE,		']',			-1,		-1, -1},
    259 	{"+button3", 		"gesture",			ID_GESTURE,		ANIM_GESTURE,	K_MOUSE3,		-1,		-1, -1},
    260 	{"messagemode", 	"chat",				ID_CHAT,		ANIM_CHAT,		't',			-1,		-1, -1},
    261 	{"messagemode2", 	"chat - team",		ID_CHAT2,		ANIM_CHAT,		-1,				-1,		-1, -1},
    262 	{"messagemode3", 	"chat - target",	ID_CHAT3,		ANIM_CHAT,		-1,				-1,		-1, -1},
    263 	{"messagemode4", 	"chat - attacker",	ID_CHAT4,		ANIM_CHAT,		-1,				-1,		-1, -1},
    264 	{(char*)NULL,		(char*)NULL,		0,				0,				-1,				-1,		-1,	-1},
    265 };
    266 
    267 static configcvar_t g_configcvars[] =
    268 {
    269 	{"cl_run",			0,					0},
    270 	{"m_pitch",			0,					0},
    271 	{"cg_autoswitch",	0,					0},
    272 	{"sensitivity",		0,					0},
    273 	{"in_joystick",		0,					0},
    274 	{"joy_threshold",	0,					0},
    275 	{"m_filter",		0,					0},
    276 	{"cl_freelook",		0,					0},
    277 	{NULL,				0,					0}
    278 };
    279 
    280 static menucommon_s *g_movement_controls[] =
    281 {
    282 	(menucommon_s *)&s_controls.alwaysrun,     
    283 	(menucommon_s *)&s_controls.run,            
    284 	(menucommon_s *)&s_controls.walkforward,
    285 	(menucommon_s *)&s_controls.backpedal,
    286 	(menucommon_s *)&s_controls.stepleft,      
    287 	(menucommon_s *)&s_controls.stepright,     
    288 	(menucommon_s *)&s_controls.moveup,        
    289 	(menucommon_s *)&s_controls.movedown,      
    290 	(menucommon_s *)&s_controls.turnleft,      
    291 	(menucommon_s *)&s_controls.turnright,     
    292 	(menucommon_s *)&s_controls.sidestep,
    293 	NULL
    294 };
    295 
    296 static menucommon_s *g_weapons_controls[] = {
    297 	(menucommon_s *)&s_controls.attack,           
    298 	(menucommon_s *)&s_controls.nextweapon,
    299 	(menucommon_s *)&s_controls.prevweapon,
    300 	(menucommon_s *)&s_controls.autoswitch,    
    301 	(menucommon_s *)&s_controls.chainsaw,         
    302 	(menucommon_s *)&s_controls.machinegun,
    303 	(menucommon_s *)&s_controls.shotgun,          
    304 	(menucommon_s *)&s_controls.grenadelauncher,
    305 	(menucommon_s *)&s_controls.rocketlauncher,   
    306 	(menucommon_s *)&s_controls.lightning,   
    307 	(menucommon_s *)&s_controls.railgun,          
    308 	(menucommon_s *)&s_controls.plasma,           
    309 	(menucommon_s *)&s_controls.bfg,              
    310 	NULL,
    311 };
    312 
    313 static menucommon_s *g_looking_controls[] = {
    314 	(menucommon_s *)&s_controls.sensitivity,
    315 	(menucommon_s *)&s_controls.smoothmouse,
    316 	(menucommon_s *)&s_controls.invertmouse,
    317 	(menucommon_s *)&s_controls.lookup,
    318 	(menucommon_s *)&s_controls.lookdown,
    319 	(menucommon_s *)&s_controls.mouselook,
    320 	(menucommon_s *)&s_controls.freelook,
    321 	(menucommon_s *)&s_controls.centerview,
    322 	(menucommon_s *)&s_controls.zoomview,
    323 	(menucommon_s *)&s_controls.joyenable,
    324 	(menucommon_s *)&s_controls.joythreshold,
    325 	NULL,
    326 };
    327 
    328 static menucommon_s *g_misc_controls[] = {
    329 	(menucommon_s *)&s_controls.showscores, 
    330 	(menucommon_s *)&s_controls.useitem,
    331 	(menucommon_s *)&s_controls.gesture,
    332 	(menucommon_s *)&s_controls.chat,
    333 	(menucommon_s *)&s_controls.chat2,
    334 	(menucommon_s *)&s_controls.chat3,
    335 	(menucommon_s *)&s_controls.chat4,
    336 	NULL,
    337 };
    338 
    339 static menucommon_s **g_controls[] = {
    340 	g_movement_controls,
    341 	g_looking_controls,
    342 	g_weapons_controls,
    343 	g_misc_controls,
    344 };
    345 
    346 /*
    347 =================
    348 Controls_InitCvars
    349 =================
    350 */
    351 static void Controls_InitCvars( void )
    352 {
    353 	int				i;
    354 	configcvar_t*	cvarptr;
    355 
    356 	cvarptr = g_configcvars;
    357 	for (i=0; ;i++,cvarptr++)
    358 	{
    359 		if (!cvarptr->name)
    360 			break;
    361 
    362 		// get current value
    363 		cvarptr->value = trap_Cvar_VariableValue( cvarptr->name );
    364 
    365 		// get default value
    366 		trap_Cvar_Reset( cvarptr->name );
    367 		cvarptr->defaultvalue = trap_Cvar_VariableValue( cvarptr->name );
    368 
    369 		// restore current value
    370 		trap_Cvar_SetValue( cvarptr->name, cvarptr->value );
    371 	}
    372 }
    373 
    374 /*
    375 =================
    376 Controls_GetCvarDefault
    377 =================
    378 */
    379 static float Controls_GetCvarDefault( char* name )
    380 {
    381 	configcvar_t*	cvarptr;
    382 	int				i;
    383 
    384 	cvarptr = g_configcvars;
    385 	for (i=0; ;i++,cvarptr++)
    386 	{
    387 		if (!cvarptr->name)
    388 			return (0);
    389 
    390 		if (!strcmp(cvarptr->name,name))
    391 			break;
    392 	}
    393 
    394 	return (cvarptr->defaultvalue);
    395 }
    396 
    397 /*
    398 =================
    399 Controls_GetCvarValue
    400 =================
    401 */
    402 static float Controls_GetCvarValue( char* name )
    403 {
    404 	configcvar_t*	cvarptr;
    405 	int				i;
    406 
    407 	cvarptr = g_configcvars;
    408 	for (i=0; ;i++,cvarptr++)
    409 	{
    410 		if (!cvarptr->name)
    411 			return (0);
    412 
    413 		if (!strcmp(cvarptr->name,name))
    414 			break;
    415 	}
    416 
    417 	return (cvarptr->value);
    418 }
    419 
    420 
    421 /*
    422 =================
    423 Controls_UpdateModel
    424 =================
    425 */
    426 static void Controls_UpdateModel( int anim ) {
    427 	VectorClear( s_controls.playerViewangles );
    428 	VectorClear( s_controls.playerMoveangles );
    429 	s_controls.playerViewangles[YAW] = 180 - 30;
    430 	s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW];
    431 	s_controls.playerLegs		     = LEGS_IDLE;
    432 	s_controls.playerTorso			 = TORSO_STAND;
    433 	s_controls.playerWeapon			 = -1;
    434 	s_controls.playerChat			 = qfalse;
    435 
    436 	switch( anim ) {
    437 	case ANIM_RUN:	
    438 		s_controls.playerLegs = LEGS_RUN;
    439 		break;
    440 
    441 	case ANIM_WALK:	
    442 		s_controls.playerLegs = LEGS_WALK;
    443 		break;
    444 
    445 	case ANIM_BACK:	
    446 		s_controls.playerLegs = LEGS_BACK;
    447 		break;
    448 
    449 	case ANIM_JUMP:	
    450 		s_controls.playerLegs = LEGS_JUMP;
    451 		break;
    452 
    453 	case ANIM_CROUCH:	
    454 		s_controls.playerLegs = LEGS_IDLECR;
    455 		break;
    456 
    457 	case ANIM_TURNLEFT:
    458 		s_controls.playerViewangles[YAW] += 90;
    459 		break;
    460 
    461 	case ANIM_TURNRIGHT:
    462 		s_controls.playerViewangles[YAW] -= 90;
    463 		break;
    464 
    465 	case ANIM_STEPLEFT:
    466 		s_controls.playerLegs = LEGS_WALK;
    467 		s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] + 90;
    468 		break;
    469 
    470 	case ANIM_STEPRIGHT:
    471 		s_controls.playerLegs = LEGS_WALK;
    472 		s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] - 90;
    473 		break;
    474 
    475 	case ANIM_LOOKUP:
    476 		s_controls.playerViewangles[PITCH] = -45;
    477 		break;
    478 
    479 	case ANIM_LOOKDOWN:
    480 		s_controls.playerViewangles[PITCH] = 45;
    481 		break;
    482 
    483 	case ANIM_WEAPON1:
    484 		s_controls.playerWeapon = WP_GAUNTLET;
    485 		break;
    486 
    487 	case ANIM_WEAPON2:
    488 		s_controls.playerWeapon = WP_MACHINEGUN;
    489 		break;
    490 
    491 	case ANIM_WEAPON3:
    492 		s_controls.playerWeapon = WP_SHOTGUN;
    493 		break;
    494 
    495 	case ANIM_WEAPON4:
    496 		s_controls.playerWeapon = WP_GRENADE_LAUNCHER;
    497 		break;
    498 
    499 	case ANIM_WEAPON5:
    500 		s_controls.playerWeapon = WP_ROCKET_LAUNCHER;
    501 		break;
    502 
    503 	case ANIM_WEAPON6:
    504 		s_controls.playerWeapon = WP_LIGHTNING;
    505 		break;
    506 
    507 	case ANIM_WEAPON7:
    508 		s_controls.playerWeapon = WP_RAILGUN;
    509 		break;
    510 
    511 	case ANIM_WEAPON8:
    512 		s_controls.playerWeapon = WP_PLASMAGUN;
    513 		break;
    514 
    515 	case ANIM_WEAPON9:
    516 		s_controls.playerWeapon = WP_BFG;
    517 		break;
    518 
    519 	case ANIM_WEAPON10:
    520 		s_controls.playerWeapon = WP_GRAPPLING_HOOK;
    521 		break;
    522 
    523 	case ANIM_ATTACK:
    524 		s_controls.playerTorso = TORSO_ATTACK;
    525 		break;
    526 
    527 	case ANIM_GESTURE:
    528 		s_controls.playerTorso = TORSO_GESTURE;
    529 		break;
    530 
    531 	case ANIM_DIE:
    532 		s_controls.playerLegs = BOTH_DEATH1;
    533 		s_controls.playerTorso = BOTH_DEATH1;
    534 		s_controls.playerWeapon = WP_NONE;
    535 		break;
    536 
    537 	case ANIM_CHAT:
    538 		s_controls.playerChat = qtrue;
    539 		break;
    540 
    541 	default:
    542 		break;
    543 	}
    544 
    545 	UI_PlayerInfo_SetInfo( &s_controls.playerinfo, s_controls.playerLegs, s_controls.playerTorso, s_controls.playerViewangles, s_controls.playerMoveangles, s_controls.playerWeapon, s_controls.playerChat );
    546 }
    547 
    548 
    549 /*
    550 =================
    551 Controls_Update
    552 =================
    553 */
    554 static void Controls_Update( void ) {
    555 	int		i;
    556 	int		j;
    557 	int		y;
    558 	menucommon_s	**controls;
    559 	menucommon_s	*control;
    560 
    561 	// disable all controls in all groups
    562 	for( i = 0; i < C_MAX; i++ ) {
    563 		controls = g_controls[i];
    564 		// bk001204 - parentheses
    565 		for( j = 0;  (control = controls[j]) ; j++ ) {
    566 			control->flags |= (QMF_HIDDEN|QMF_INACTIVE);
    567 		}
    568 	}
    569 
    570 	controls = g_controls[s_controls.section];
    571 
    572 	// enable controls in active group (and count number of items for vertical centering)
    573 	// bk001204 - parentheses
    574 	for( j = 0;  (control = controls[j]) ; j++ ) {
    575 		control->flags &= ~(QMF_GRAYED|QMF_HIDDEN|QMF_INACTIVE);
    576 	}
    577 
    578 	// position controls
    579 	y = ( SCREEN_HEIGHT - j * SMALLCHAR_HEIGHT ) / 2;
    580 	// bk001204 - parentheses
    581 	for( j = 0;	(control = controls[j]) ; j++, y += SMALLCHAR_HEIGHT ) {
    582 		control->x      = 320;
    583 		control->y      = y;
    584 		control->left   = 320 - 19*SMALLCHAR_WIDTH;
    585 		control->right  = 320 + 21*SMALLCHAR_WIDTH;
    586 		control->top    = y;
    587 		control->bottom = y + SMALLCHAR_HEIGHT;
    588 	}
    589 
    590 	if( s_controls.waitingforkey ) {
    591 		// disable everybody
    592 		for( i = 0; i < s_controls.menu.nitems; i++ ) {
    593 			((menucommon_s*)(s_controls.menu.items[i]))->flags |= QMF_GRAYED;
    594 		}
    595 
    596 		// enable action item
    597 		((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->flags &= ~QMF_GRAYED;
    598 
    599 		// don't gray out player's name
    600 		s_controls.name.generic.flags &= ~QMF_GRAYED;
    601 
    602 		return;
    603 	}
    604 
    605 	// enable everybody
    606 	for( i = 0; i < s_controls.menu.nitems; i++ ) {
    607 		((menucommon_s*)(s_controls.menu.items[i]))->flags &= ~QMF_GRAYED;
    608 	}
    609 
    610 	// makes sure flags are right on the group selection controls
    611 	s_controls.looking.generic.flags  &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    612 	s_controls.movement.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    613 	s_controls.weapons.generic.flags  &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    614 	s_controls.misc.generic.flags     &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    615 
    616 	s_controls.looking.generic.flags  |= QMF_PULSEIFFOCUS;
    617 	s_controls.movement.generic.flags |= QMF_PULSEIFFOCUS;
    618 	s_controls.weapons.generic.flags  |= QMF_PULSEIFFOCUS;
    619 	s_controls.misc.generic.flags     |= QMF_PULSEIFFOCUS;
    620 
    621 	// set buttons
    622 	switch( s_controls.section ) {
    623 	case C_MOVEMENT:
    624 		s_controls.movement.generic.flags &= ~QMF_PULSEIFFOCUS;
    625 		s_controls.movement.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    626 		break;
    627 	
    628 	case C_LOOKING:
    629 		s_controls.looking.generic.flags &= ~QMF_PULSEIFFOCUS;
    630 		s_controls.looking.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    631 		break;
    632 	
    633 	case C_WEAPONS:
    634 		s_controls.weapons.generic.flags &= ~QMF_PULSEIFFOCUS;
    635 		s_controls.weapons.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    636 		break;		
    637 
    638 	case C_MISC:
    639 		s_controls.misc.generic.flags &= ~QMF_PULSEIFFOCUS;
    640 		s_controls.misc.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
    641 		break;
    642 	}
    643 }
    644 
    645 
    646 /*
    647 =================
    648 Controls_DrawKeyBinding
    649 =================
    650 */
    651 static void Controls_DrawKeyBinding( void *self )
    652 {
    653 	menuaction_s*	a;
    654 	int				x;
    655 	int				y;
    656 	int				b1;
    657 	int				b2;
    658 	qboolean		c;
    659 	char			name[32];
    660 	char			name2[32];
    661 
    662 	a = (menuaction_s*) self;
    663 
    664 	x =	a->generic.x;
    665 	y = a->generic.y;
    666 
    667 	c = (Menu_ItemAtCursor( a->generic.parent ) == a);
    668 
    669 	b1 = g_bindings[a->generic.id].bind1;
    670 	if (b1 == -1)
    671 		strcpy(name,"???");
    672 	else
    673 	{
    674 		trap_Key_KeynumToStringBuf( b1, name, 32 );
    675 		Q_strupr(name);
    676 
    677 		b2 = g_bindings[a->generic.id].bind2;
    678 		if (b2 != -1)
    679 		{
    680 			trap_Key_KeynumToStringBuf( b2, name2, 32 );
    681 			Q_strupr(name2);
    682 
    683 			strcat( name, " or " );
    684 			strcat( name, name2 );
    685 		}
    686 	}
    687 
    688 	if (c)
    689 	{
    690 		UI_FillRect( a->generic.left, a->generic.top, a->generic.right-a->generic.left+1, a->generic.bottom-a->generic.top+1, listbar_color ); 
    691 
    692 		UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_highlight );
    693 		UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT|UI_PULSE, text_color_highlight );
    694 
    695 		if (s_controls.waitingforkey)
    696 		{
    697 			UI_DrawChar( x, y, '=', UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight);
    698 			UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Waiting for new key ... ESCAPE to cancel", UI_SMALLFONT|UI_CENTER|UI_PULSE, colorWhite );
    699 		}
    700 		else
    701 		{
    702 			UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight);
    703 			UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.78, "Press ENTER or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite );
    704 			UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.82, "Press BACKSPACE to clear", UI_SMALLFONT|UI_CENTER, colorWhite );
    705 		}
    706 	}
    707 	else
    708 	{
    709 		if (a->generic.flags & QMF_GRAYED)
    710 		{
    711 			UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_disabled );
    712 			UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, text_color_disabled );
    713 		}
    714 		else
    715 		{
    716 			UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, controls_binding_color );
    717 			UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, controls_binding_color );
    718 		}
    719 	}
    720 }
    721 
    722 /*
    723 =================
    724 Controls_StatusBar
    725 =================
    726 */
    727 static void Controls_StatusBar( void *self )
    728 {
    729 	UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Use Arrow Keys or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite );
    730 }
    731 
    732 
    733 /*
    734 =================
    735 Controls_DrawPlayer
    736 =================
    737 */
    738 static void Controls_DrawPlayer( void *self ) {
    739 	menubitmap_s	*b;
    740 	char			buf[MAX_QPATH];
    741 
    742 	trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) );
    743 	if ( strcmp( buf, s_controls.playerModel ) != 0 ) {
    744 		UI_PlayerInfo_SetModel( &s_controls.playerinfo, buf );
    745 		strcpy( s_controls.playerModel, buf );
    746 		Controls_UpdateModel( ANIM_IDLE );
    747 	}
    748 
    749 	b = (menubitmap_s*) self;
    750 	UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_controls.playerinfo, uis.realtime/2 );
    751 }
    752 
    753 
    754 /*
    755 =================
    756 Controls_GetKeyAssignment
    757 =================
    758 */
    759 static void Controls_GetKeyAssignment (char *command, int *twokeys)
    760 {
    761 	int		count;
    762 	int		j;
    763 	char	b[256];
    764 
    765 	twokeys[0] = twokeys[1] = -1;
    766 	count = 0;
    767 
    768 	for ( j = 0; j < 256; j++ )
    769 	{
    770 		trap_Key_GetBindingBuf( j, b, 256 );
    771 		if ( *b == 0 ) {
    772 			continue;
    773 		}
    774 		if ( !Q_stricmp( b, command ) ) {
    775 			twokeys[count] = j;
    776 			count++;
    777 			if (count == 2)
    778 				break;
    779 		}
    780 	}
    781 }
    782 
    783 /*
    784 =================
    785 Controls_GetConfig
    786 =================
    787 */
    788 static void Controls_GetConfig( void )
    789 {
    790 	int		i;
    791 	int		twokeys[2];
    792 	bind_t*	bindptr;
    793 
    794 	// put the bindings into a local store
    795 	bindptr = g_bindings;
    796 
    797 	// iterate each command, get its numeric binding
    798 	for (i=0; ;i++,bindptr++)
    799 	{
    800 		if (!bindptr->label)
    801 			break;
    802 
    803 		Controls_GetKeyAssignment(bindptr->command, twokeys);
    804 
    805 		bindptr->bind1 = twokeys[0];
    806 		bindptr->bind2 = twokeys[1];
    807 	}
    808 
    809 	s_controls.invertmouse.curvalue  = Controls_GetCvarValue( "m_pitch" ) < 0;
    810 	s_controls.smoothmouse.curvalue  = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "m_filter" ) );
    811 	s_controls.alwaysrun.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_run" ) );
    812 	s_controls.autoswitch.curvalue   = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cg_autoswitch" ) );
    813 	s_controls.sensitivity.curvalue  = UI_ClampCvar( 2, 30, Controls_GetCvarValue( "sensitivity" ) );
    814 	s_controls.joyenable.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "in_joystick" ) );
    815 	s_controls.joythreshold.curvalue = UI_ClampCvar( 0.05f, 0.75f, Controls_GetCvarValue( "joy_threshold" ) );
    816 	s_controls.freelook.curvalue     = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_freelook" ) );
    817 }
    818 
    819 /*
    820 =================
    821 Controls_SetConfig
    822 =================
    823 */
    824 static void Controls_SetConfig( void )
    825 {
    826 	int		i;
    827 	bind_t*	bindptr;
    828 
    829 	// set the bindings from the local store
    830 	bindptr = g_bindings;
    831 
    832 	// iterate each command, get its numeric binding
    833 	for (i=0; ;i++,bindptr++)
    834 	{
    835 		if (!bindptr->label)
    836 			break;
    837 
    838 		if (bindptr->bind1 != -1)
    839 		{	
    840 			trap_Key_SetBinding( bindptr->bind1, bindptr->command );
    841 
    842 			if (bindptr->bind2 != -1)
    843 				trap_Key_SetBinding( bindptr->bind2, bindptr->command );
    844 		}
    845 	}
    846 
    847 	if ( s_controls.invertmouse.curvalue )
    848 		trap_Cvar_SetValue( "m_pitch", -fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
    849 	else
    850 		trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
    851 
    852 	trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue );
    853 	trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue );
    854 	trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue );
    855 	trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue );
    856 	trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue );
    857 	trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue );
    858 	trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue );
    859 	trap_Cmd_ExecuteText( EXEC_APPEND, "in_restart\n" );
    860 }
    861 
    862 /*
    863 =================
    864 Controls_SetDefaults
    865 =================
    866 */
    867 static void Controls_SetDefaults( void )
    868 {
    869 	int	i;
    870 	bind_t*	bindptr;
    871 
    872 	// set the bindings from the local store
    873 	bindptr = g_bindings;
    874 
    875 	// iterate each command, set its default binding
    876 	for (i=0; ;i++,bindptr++)
    877 	{
    878 		if (!bindptr->label)
    879 			break;
    880 
    881 		bindptr->bind1 = bindptr->defaultbind1;
    882 		bindptr->bind2 = bindptr->defaultbind2;
    883 	}
    884 
    885 	s_controls.invertmouse.curvalue  = Controls_GetCvarDefault( "m_pitch" ) < 0;
    886 	s_controls.smoothmouse.curvalue  = Controls_GetCvarDefault( "m_filter" );
    887 	s_controls.alwaysrun.curvalue    = Controls_GetCvarDefault( "cl_run" );
    888 	s_controls.autoswitch.curvalue   = Controls_GetCvarDefault( "cg_autoswitch" );
    889 	s_controls.sensitivity.curvalue  = Controls_GetCvarDefault( "sensitivity" );
    890 	s_controls.joyenable.curvalue    = Controls_GetCvarDefault( "in_joystick" );
    891 	s_controls.joythreshold.curvalue = Controls_GetCvarDefault( "joy_threshold" );
    892 	s_controls.freelook.curvalue     = Controls_GetCvarDefault( "cl_freelook" );
    893 }
    894 
    895 /*
    896 =================
    897 Controls_MenuKey
    898 =================
    899 */
    900 static sfxHandle_t Controls_MenuKey( int key )
    901 {
    902 	int			id;
    903 	int			i;
    904 	qboolean	found;
    905 	bind_t*		bindptr;
    906 	found = qfalse;
    907 
    908 	if (!s_controls.waitingforkey)
    909 	{
    910 		switch (key)
    911 		{
    912 			case K_BACKSPACE:
    913 			case K_DEL:
    914 			case K_KP_DEL:
    915 				key = -1;
    916 				break;
    917 		
    918 			case K_MOUSE2:
    919 			case K_ESCAPE:
    920 				if (s_controls.changesmade)
    921 					Controls_SetConfig();
    922 				goto ignorekey;	
    923 
    924 			default:
    925 				goto ignorekey;
    926 		}
    927 	}
    928 	else
    929 	{
    930 		if (key & K_CHAR_FLAG)
    931 			goto ignorekey;
    932 
    933 		switch (key)
    934 		{
    935 			case K_ESCAPE:
    936 				s_controls.waitingforkey = qfalse;
    937 				Controls_Update();
    938 				return (menu_out_sound);
    939 	
    940 			case '`':
    941 				goto ignorekey;
    942 		}
    943 	}
    944 
    945 	s_controls.changesmade = qtrue;
    946 	
    947 	if (key != -1)
    948 	{
    949 		// remove from any other bind
    950 		bindptr = g_bindings;
    951 		for (i=0; ;i++,bindptr++)
    952 		{
    953 			if (!bindptr->label)	
    954 				break;
    955 
    956 			if (bindptr->bind2 == key)
    957 				bindptr->bind2 = -1;
    958 
    959 			if (bindptr->bind1 == key)
    960 			{
    961 				bindptr->bind1 = bindptr->bind2;	
    962 				bindptr->bind2 = -1;
    963 			}
    964 		}
    965 	}
    966 
    967 	// assign key to local store
    968 	id      = ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->id;
    969 	bindptr = g_bindings;
    970 	for (i=0; ;i++,bindptr++)
    971 	{
    972 		if (!bindptr->label)	
    973 			break;
    974 		
    975 		if (bindptr->id == id)
    976 		{
    977 			found = qtrue;
    978 			if (key == -1)
    979 			{
    980 				if( bindptr->bind1 != -1 ) {
    981 					trap_Key_SetBinding( bindptr->bind1, "" );
    982 					bindptr->bind1 = -1;
    983 				}
    984 				if( bindptr->bind2 != -1 ) {
    985 					trap_Key_SetBinding( bindptr->bind2, "" );
    986 					bindptr->bind2 = -1;
    987 				}
    988 			}
    989 			else if (bindptr->bind1 == -1) {
    990 				bindptr->bind1 = key;
    991 			}
    992 			else if (bindptr->bind1 != key && bindptr->bind2 == -1) {
    993 				bindptr->bind2 = key;
    994 			}
    995 			else
    996 			{
    997 				trap_Key_SetBinding( bindptr->bind1, "" );
    998 				trap_Key_SetBinding( bindptr->bind2, "" );
    999 				bindptr->bind1 = key;
   1000 				bindptr->bind2 = -1;
   1001 			}						
   1002 			break;
   1003 		}
   1004 	}				
   1005 		
   1006 	s_controls.waitingforkey = qfalse;
   1007 
   1008 	if (found)
   1009 	{	
   1010 		Controls_Update();
   1011 		return (menu_out_sound);
   1012 	}
   1013 
   1014 ignorekey:
   1015 	return Menu_DefaultKey( &s_controls.menu, key );
   1016 }
   1017 
   1018 /*
   1019 =================
   1020 Controls_ResetDefaults_Action
   1021 =================
   1022 */
   1023 static void Controls_ResetDefaults_Action( qboolean result ) {
   1024 	if( !result ) {
   1025 		return;
   1026 	}
   1027 
   1028 	s_controls.changesmade = qtrue;
   1029 	Controls_SetDefaults();
   1030 	Controls_Update();
   1031 }
   1032 
   1033 /*
   1034 =================
   1035 Controls_ResetDefaults_Draw
   1036 =================
   1037 */
   1038 static void Controls_ResetDefaults_Draw( void ) {
   1039 	UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This will reset all", UI_CENTER|UI_SMALLFONT, color_yellow );
   1040 	UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "controls to their default values.", UI_CENTER|UI_SMALLFONT, color_yellow );
   1041 }
   1042 
   1043 /*
   1044 =================
   1045 Controls_MenuEvent
   1046 =================
   1047 */
   1048 static void Controls_MenuEvent( void* ptr, int event )
   1049 {
   1050 	switch (((menucommon_s*)ptr)->id)
   1051 	{
   1052 		case ID_MOVEMENT:
   1053 			if (event == QM_ACTIVATED)
   1054 			{
   1055 				s_controls.section = C_MOVEMENT; 
   1056 				Controls_Update();
   1057 			}
   1058 			break;
   1059 
   1060 		case ID_LOOKING:
   1061 			if (event == QM_ACTIVATED)
   1062 			{
   1063 				s_controls.section = C_LOOKING; 
   1064 				Controls_Update();
   1065 			}
   1066 			break;
   1067 
   1068 		case ID_WEAPONS:
   1069 			if (event == QM_ACTIVATED)
   1070 			{
   1071 				s_controls.section = C_WEAPONS; 
   1072 				Controls_Update();
   1073 			}
   1074 			break;
   1075 
   1076 		case ID_MISC:
   1077 			if (event == QM_ACTIVATED)
   1078 			{
   1079 				s_controls.section = C_MISC; 
   1080 				Controls_Update();
   1081 			}
   1082 			break;
   1083 
   1084 		case ID_DEFAULTS:
   1085 			if (event == QM_ACTIVATED)
   1086 			{
   1087 				UI_ConfirmMenu( "SET TO DEFAULTS?", Controls_ResetDefaults_Draw, Controls_ResetDefaults_Action );
   1088 			}
   1089 			break;
   1090 
   1091 		case ID_BACK:
   1092 			if (event == QM_ACTIVATED)
   1093 			{
   1094 				if (s_controls.changesmade)
   1095 					Controls_SetConfig();
   1096 				UI_PopMenu();
   1097 			}
   1098 			break;
   1099 
   1100 		case ID_SAVEANDEXIT:
   1101 			if (event == QM_ACTIVATED)
   1102 			{
   1103 				Controls_SetConfig();
   1104 				UI_PopMenu();
   1105 			}
   1106 			break;
   1107 
   1108 		case ID_EXIT:
   1109 			if (event == QM_ACTIVATED)
   1110 			{
   1111 				UI_PopMenu();
   1112 			}
   1113 			break;
   1114 
   1115 		case ID_FREELOOK:
   1116 		case ID_MOUSESPEED:
   1117 		case ID_INVERTMOUSE:
   1118 		case ID_SMOOTHMOUSE:
   1119 		case ID_ALWAYSRUN:
   1120 		case ID_AUTOSWITCH:
   1121 		case ID_JOYENABLE:
   1122 		case ID_JOYTHRESHOLD:
   1123 			if (event == QM_ACTIVATED)
   1124 			{
   1125 				s_controls.changesmade = qtrue;
   1126 			}
   1127 			break;		
   1128 	}
   1129 }
   1130 
   1131 /*
   1132 =================
   1133 Controls_ActionEvent
   1134 =================
   1135 */
   1136 static void Controls_ActionEvent( void* ptr, int event )
   1137 {
   1138 	if (event == QM_LOSTFOCUS)
   1139 	{
   1140 		Controls_UpdateModel( ANIM_IDLE );
   1141 	}
   1142 	else if (event == QM_GOTFOCUS)
   1143 	{
   1144 		Controls_UpdateModel( g_bindings[((menucommon_s*)ptr)->id].anim );
   1145 	}
   1146 	else if ((event == QM_ACTIVATED) && !s_controls.waitingforkey)
   1147 	{
   1148 		s_controls.waitingforkey = 1;
   1149 		Controls_Update();
   1150 	}
   1151 }
   1152 
   1153 /*
   1154 =================
   1155 Controls_InitModel
   1156 =================
   1157 */
   1158 static void Controls_InitModel( void )
   1159 {
   1160 	memset( &s_controls.playerinfo, 0, sizeof(playerInfo_t) );
   1161 
   1162 	UI_PlayerInfo_SetModel( &s_controls.playerinfo, UI_Cvar_VariableString( "model" ) );
   1163 
   1164 	Controls_UpdateModel( ANIM_IDLE );
   1165 }
   1166 
   1167 /*
   1168 =================
   1169 Controls_InitWeapons
   1170 =================
   1171 */
   1172 static void Controls_InitWeapons( void ) {
   1173 	gitem_t *	item;
   1174 
   1175 	for ( item = bg_itemlist + 1 ; item->classname ; item++ ) {
   1176 		if ( item->giType != IT_WEAPON ) {
   1177 			continue;
   1178 		}
   1179 		trap_R_RegisterModel( item->world_model[0] );
   1180 	}
   1181 }
   1182 
   1183 /*
   1184 =================
   1185 Controls_MenuInit
   1186 =================
   1187 */
   1188 static void Controls_MenuInit( void )
   1189 {
   1190 	static char playername[32];
   1191 
   1192 	// zero set all our globals
   1193 	memset( &s_controls, 0 ,sizeof(controls_t) );
   1194 
   1195 	Controls_Cache();
   1196 
   1197 	s_controls.menu.key        = Controls_MenuKey;
   1198 	s_controls.menu.wrapAround = qtrue;
   1199 	s_controls.menu.fullscreen = qtrue;
   1200 
   1201 	s_controls.banner.generic.type	= MTYPE_BTEXT;
   1202 	s_controls.banner.generic.flags	= QMF_CENTER_JUSTIFY;
   1203 	s_controls.banner.generic.x		= 320;
   1204 	s_controls.banner.generic.y		= 16;
   1205 	s_controls.banner.string		= "CONTROLS";
   1206 	s_controls.banner.color			= color_white;
   1207 	s_controls.banner.style			= UI_CENTER;
   1208 
   1209 	s_controls.framel.generic.type  = MTYPE_BITMAP;
   1210 	s_controls.framel.generic.name  = ART_FRAMEL;
   1211 	s_controls.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
   1212 	s_controls.framel.generic.x     = 0;
   1213 	s_controls.framel.generic.y     = 78;
   1214 	s_controls.framel.width  	    = 256;
   1215 	s_controls.framel.height  	    = 329;
   1216 
   1217 	s_controls.framer.generic.type  = MTYPE_BITMAP;
   1218 	s_controls.framer.generic.name  = ART_FRAMER;
   1219 	s_controls.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
   1220 	s_controls.framer.generic.x     = 376;
   1221 	s_controls.framer.generic.y     = 76;
   1222 	s_controls.framer.width  	    = 256;
   1223 	s_controls.framer.height  	    = 334;
   1224 
   1225 	s_controls.looking.generic.type     = MTYPE_PTEXT;
   1226 	s_controls.looking.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
   1227 	s_controls.looking.generic.id	    = ID_LOOKING;
   1228 	s_controls.looking.generic.callback	= Controls_MenuEvent;
   1229 	s_controls.looking.generic.x	    = 152;
   1230 	s_controls.looking.generic.y	    = 240 - 2 * PROP_HEIGHT;
   1231 	s_controls.looking.string			= "LOOK";
   1232 	s_controls.looking.style			= UI_RIGHT;
   1233 	s_controls.looking.color			= color_red;
   1234 
   1235 	s_controls.movement.generic.type     = MTYPE_PTEXT;
   1236 	s_controls.movement.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
   1237 	s_controls.movement.generic.id	     = ID_MOVEMENT;
   1238 	s_controls.movement.generic.callback = Controls_MenuEvent;
   1239 	s_controls.movement.generic.x	     = 152;
   1240 	s_controls.movement.generic.y	     = 240 - PROP_HEIGHT;
   1241 	s_controls.movement.string			= "MOVE";
   1242 	s_controls.movement.style			= UI_RIGHT;
   1243 	s_controls.movement.color			= color_red;
   1244 
   1245 	s_controls.weapons.generic.type	    = MTYPE_PTEXT;
   1246 	s_controls.weapons.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
   1247 	s_controls.weapons.generic.id	    = ID_WEAPONS;
   1248 	s_controls.weapons.generic.callback	= Controls_MenuEvent;
   1249 	s_controls.weapons.generic.x	    = 152;
   1250 	s_controls.weapons.generic.y	    = 240;
   1251 	s_controls.weapons.string			= "SHOOT";
   1252 	s_controls.weapons.style			= UI_RIGHT;
   1253 	s_controls.weapons.color			= color_red;
   1254 
   1255 	s_controls.misc.generic.type	 = MTYPE_PTEXT;
   1256 	s_controls.misc.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
   1257 	s_controls.misc.generic.id	     = ID_MISC;
   1258 	s_controls.misc.generic.callback = Controls_MenuEvent;
   1259 	s_controls.misc.generic.x		 = 152;
   1260 	s_controls.misc.generic.y		 = 240 + PROP_HEIGHT;
   1261 	s_controls.misc.string			= "MISC";
   1262 	s_controls.misc.style			= UI_RIGHT;
   1263 	s_controls.misc.color			= color_red;
   1264 
   1265 	s_controls.back.generic.type	 = MTYPE_BITMAP;
   1266 	s_controls.back.generic.name     = ART_BACK0;
   1267 	s_controls.back.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
   1268 	s_controls.back.generic.x		 = 0;
   1269 	s_controls.back.generic.y		 = 480-64;
   1270 	s_controls.back.generic.id	     = ID_BACK;
   1271 	s_controls.back.generic.callback = Controls_MenuEvent;
   1272 	s_controls.back.width  		     = 128;
   1273 	s_controls.back.height  		 = 64;
   1274 	s_controls.back.focuspic         = ART_BACK1;
   1275 
   1276 	s_controls.player.generic.type      = MTYPE_BITMAP;
   1277 	s_controls.player.generic.flags     = QMF_INACTIVE;
   1278 	s_controls.player.generic.ownerdraw = Controls_DrawPlayer;
   1279 	s_controls.player.generic.x	        = 400;
   1280 	s_controls.player.generic.y	        = -40;
   1281 	s_controls.player.width	            = 32*10;
   1282 	s_controls.player.height            = 56*10;
   1283 
   1284 	s_controls.walkforward.generic.type	     = MTYPE_ACTION;
   1285 	s_controls.walkforward.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1286 	s_controls.walkforward.generic.callback  = Controls_ActionEvent;
   1287 	s_controls.walkforward.generic.ownerdraw = Controls_DrawKeyBinding;
   1288 	s_controls.walkforward.generic.id 	     = ID_FORWARD;
   1289 
   1290 	s_controls.backpedal.generic.type	   = MTYPE_ACTION;
   1291 	s_controls.backpedal.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1292 	s_controls.backpedal.generic.callback  = Controls_ActionEvent;
   1293 	s_controls.backpedal.generic.ownerdraw = Controls_DrawKeyBinding;
   1294 	s_controls.backpedal.generic.id 	   = ID_BACKPEDAL;
   1295 
   1296 	s_controls.stepleft.generic.type	  = MTYPE_ACTION;
   1297 	s_controls.stepleft.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1298 	s_controls.stepleft.generic.callback  = Controls_ActionEvent;
   1299 	s_controls.stepleft.generic.ownerdraw = Controls_DrawKeyBinding;
   1300 	s_controls.stepleft.generic.id 		  = ID_MOVELEFT;
   1301 
   1302 	s_controls.stepright.generic.type	   = MTYPE_ACTION;
   1303 	s_controls.stepright.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1304 	s_controls.stepright.generic.callback  = Controls_ActionEvent;
   1305 	s_controls.stepright.generic.ownerdraw = Controls_DrawKeyBinding;
   1306 	s_controls.stepright.generic.id        = ID_MOVERIGHT;
   1307 
   1308 	s_controls.moveup.generic.type	    = MTYPE_ACTION;
   1309 	s_controls.moveup.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1310 	s_controls.moveup.generic.callback  = Controls_ActionEvent;
   1311 	s_controls.moveup.generic.ownerdraw = Controls_DrawKeyBinding;
   1312 	s_controls.moveup.generic.id        = ID_MOVEUP;
   1313 
   1314 	s_controls.movedown.generic.type	  = MTYPE_ACTION;
   1315 	s_controls.movedown.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1316 	s_controls.movedown.generic.callback  = Controls_ActionEvent;
   1317 	s_controls.movedown.generic.ownerdraw = Controls_DrawKeyBinding;
   1318 	s_controls.movedown.generic.id        = ID_MOVEDOWN;
   1319 
   1320 	s_controls.turnleft.generic.type	  = MTYPE_ACTION;
   1321 	s_controls.turnleft.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1322 	s_controls.turnleft.generic.callback  = Controls_ActionEvent;
   1323 	s_controls.turnleft.generic.ownerdraw = Controls_DrawKeyBinding;
   1324 	s_controls.turnleft.generic.id        = ID_LEFT;
   1325 
   1326 	s_controls.turnright.generic.type	   = MTYPE_ACTION;
   1327 	s_controls.turnright.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1328 	s_controls.turnright.generic.callback  = Controls_ActionEvent;
   1329 	s_controls.turnright.generic.ownerdraw = Controls_DrawKeyBinding;
   1330 	s_controls.turnright.generic.id        = ID_RIGHT;
   1331 
   1332 	s_controls.sidestep.generic.type	  = MTYPE_ACTION;
   1333 	s_controls.sidestep.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1334 	s_controls.sidestep.generic.callback  = Controls_ActionEvent;
   1335 	s_controls.sidestep.generic.ownerdraw = Controls_DrawKeyBinding;
   1336 	s_controls.sidestep.generic.id        = ID_STRAFE;
   1337 
   1338 	s_controls.run.generic.type	     = MTYPE_ACTION;
   1339 	s_controls.run.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1340 	s_controls.run.generic.callback  = Controls_ActionEvent;
   1341 	s_controls.run.generic.ownerdraw = Controls_DrawKeyBinding;
   1342 	s_controls.run.generic.id        = ID_SPEED;
   1343 
   1344 	s_controls.chainsaw.generic.type	  = MTYPE_ACTION;
   1345 	s_controls.chainsaw.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1346 	s_controls.chainsaw.generic.callback  = Controls_ActionEvent;
   1347 	s_controls.chainsaw.generic.ownerdraw = Controls_DrawKeyBinding;
   1348 	s_controls.chainsaw.generic.id        = ID_WEAPON1;
   1349 
   1350 	s_controls.machinegun.generic.type	    = MTYPE_ACTION;
   1351 	s_controls.machinegun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1352 	s_controls.machinegun.generic.callback  = Controls_ActionEvent;
   1353 	s_controls.machinegun.generic.ownerdraw = Controls_DrawKeyBinding;
   1354 	s_controls.machinegun.generic.id        = ID_WEAPON2;
   1355 
   1356 	s_controls.shotgun.generic.type	     = MTYPE_ACTION;
   1357 	s_controls.shotgun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1358 	s_controls.shotgun.generic.callback  = Controls_ActionEvent;
   1359 	s_controls.shotgun.generic.ownerdraw = Controls_DrawKeyBinding;
   1360 	s_controls.shotgun.generic.id        = ID_WEAPON3;
   1361 
   1362 	s_controls.grenadelauncher.generic.type	     = MTYPE_ACTION;
   1363 	s_controls.grenadelauncher.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1364 	s_controls.grenadelauncher.generic.callback  = Controls_ActionEvent;
   1365 	s_controls.grenadelauncher.generic.ownerdraw = Controls_DrawKeyBinding;
   1366 	s_controls.grenadelauncher.generic.id        = ID_WEAPON4;
   1367 
   1368 	s_controls.rocketlauncher.generic.type	    = MTYPE_ACTION;
   1369 	s_controls.rocketlauncher.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1370 	s_controls.rocketlauncher.generic.callback  = Controls_ActionEvent;
   1371 	s_controls.rocketlauncher.generic.ownerdraw = Controls_DrawKeyBinding;
   1372 	s_controls.rocketlauncher.generic.id        = ID_WEAPON5;
   1373 
   1374 	s_controls.lightning.generic.type	   = MTYPE_ACTION;
   1375 	s_controls.lightning.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1376 	s_controls.lightning.generic.callback  = Controls_ActionEvent;
   1377 	s_controls.lightning.generic.ownerdraw = Controls_DrawKeyBinding;
   1378 	s_controls.lightning.generic.id        = ID_WEAPON6;
   1379 
   1380 	s_controls.railgun.generic.type	     = MTYPE_ACTION;
   1381 	s_controls.railgun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1382 	s_controls.railgun.generic.callback  = Controls_ActionEvent;
   1383 	s_controls.railgun.generic.ownerdraw = Controls_DrawKeyBinding;
   1384 	s_controls.railgun.generic.id        = ID_WEAPON7;
   1385 
   1386 	s_controls.plasma.generic.type	    = MTYPE_ACTION;
   1387 	s_controls.plasma.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1388 	s_controls.plasma.generic.callback  = Controls_ActionEvent;
   1389 	s_controls.plasma.generic.ownerdraw = Controls_DrawKeyBinding;
   1390 	s_controls.plasma.generic.id        = ID_WEAPON8;
   1391 
   1392 	s_controls.bfg.generic.type	     = MTYPE_ACTION;
   1393 	s_controls.bfg.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1394 	s_controls.bfg.generic.callback  = Controls_ActionEvent;
   1395 	s_controls.bfg.generic.ownerdraw = Controls_DrawKeyBinding;
   1396 	s_controls.bfg.generic.id        = ID_WEAPON9;
   1397 
   1398 	s_controls.attack.generic.type	    = MTYPE_ACTION;
   1399 	s_controls.attack.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1400 	s_controls.attack.generic.callback  = Controls_ActionEvent;
   1401 	s_controls.attack.generic.ownerdraw = Controls_DrawKeyBinding;
   1402 	s_controls.attack.generic.id        = ID_ATTACK;
   1403 
   1404 	s_controls.prevweapon.generic.type	    = MTYPE_ACTION;
   1405 	s_controls.prevweapon.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1406 	s_controls.prevweapon.generic.callback  = Controls_ActionEvent;
   1407 	s_controls.prevweapon.generic.ownerdraw = Controls_DrawKeyBinding;
   1408 	s_controls.prevweapon.generic.id        = ID_WEAPPREV;
   1409 
   1410 	s_controls.nextweapon.generic.type	    = MTYPE_ACTION;
   1411 	s_controls.nextweapon.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1412 	s_controls.nextweapon.generic.callback  = Controls_ActionEvent;
   1413 	s_controls.nextweapon.generic.ownerdraw = Controls_DrawKeyBinding;
   1414 	s_controls.nextweapon.generic.id        = ID_WEAPNEXT;
   1415 
   1416 	s_controls.lookup.generic.type	    = MTYPE_ACTION;
   1417 	s_controls.lookup.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1418 	s_controls.lookup.generic.callback  = Controls_ActionEvent;
   1419 	s_controls.lookup.generic.ownerdraw = Controls_DrawKeyBinding;
   1420 	s_controls.lookup.generic.id        = ID_LOOKUP;
   1421 
   1422 	s_controls.lookdown.generic.type	  = MTYPE_ACTION;
   1423 	s_controls.lookdown.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1424 	s_controls.lookdown.generic.callback  = Controls_ActionEvent;
   1425 	s_controls.lookdown.generic.ownerdraw = Controls_DrawKeyBinding;
   1426 	s_controls.lookdown.generic.id        = ID_LOOKDOWN;
   1427 
   1428 	s_controls.mouselook.generic.type	   = MTYPE_ACTION;
   1429 	s_controls.mouselook.generic.flags     = QMF_LEFT_JUSTIFY|QMF_HIGHLIGHT_IF_FOCUS|QMF_GRAYED|QMF_HIDDEN;
   1430 	s_controls.mouselook.generic.callback  = Controls_ActionEvent;
   1431 	s_controls.mouselook.generic.ownerdraw = Controls_DrawKeyBinding;
   1432 	s_controls.mouselook.generic.id        = ID_MOUSELOOK;
   1433 
   1434 	s_controls.freelook.generic.type		= MTYPE_RADIOBUTTON;
   1435 	s_controls.freelook.generic.flags		= QMF_SMALLFONT;
   1436 	s_controls.freelook.generic.x			= SCREEN_WIDTH/2;
   1437 	s_controls.freelook.generic.name		= "free look";
   1438 	s_controls.freelook.generic.id			= ID_FREELOOK;
   1439 	s_controls.freelook.generic.callback	= Controls_MenuEvent;
   1440 	s_controls.freelook.generic.statusbar	= Controls_StatusBar;
   1441 
   1442 	s_controls.centerview.generic.type	    = MTYPE_ACTION;
   1443 	s_controls.centerview.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1444 	s_controls.centerview.generic.callback  = Controls_ActionEvent;
   1445 	s_controls.centerview.generic.ownerdraw = Controls_DrawKeyBinding;
   1446 	s_controls.centerview.generic.id        = ID_CENTERVIEW;
   1447 
   1448 	s_controls.zoomview.generic.type	  = MTYPE_ACTION;
   1449 	s_controls.zoomview.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1450 	s_controls.zoomview.generic.callback  = Controls_ActionEvent;
   1451 	s_controls.zoomview.generic.ownerdraw = Controls_DrawKeyBinding;
   1452 	s_controls.zoomview.generic.id        = ID_ZOOMVIEW;
   1453 
   1454 	s_controls.useitem.generic.type	     = MTYPE_ACTION;
   1455 	s_controls.useitem.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1456 	s_controls.useitem.generic.callback  = Controls_ActionEvent;
   1457 	s_controls.useitem.generic.ownerdraw = Controls_DrawKeyBinding;
   1458 	s_controls.useitem.generic.id        = ID_USEITEM;
   1459 
   1460 	s_controls.showscores.generic.type	    = MTYPE_ACTION;
   1461 	s_controls.showscores.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1462 	s_controls.showscores.generic.callback  = Controls_ActionEvent;
   1463 	s_controls.showscores.generic.ownerdraw = Controls_DrawKeyBinding;
   1464 	s_controls.showscores.generic.id        = ID_SHOWSCORES;
   1465 
   1466 	s_controls.invertmouse.generic.type      = MTYPE_RADIOBUTTON;
   1467 	s_controls.invertmouse.generic.flags	 = QMF_SMALLFONT;
   1468 	s_controls.invertmouse.generic.x	     = SCREEN_WIDTH/2;
   1469 	s_controls.invertmouse.generic.name	     = "invert mouse";
   1470 	s_controls.invertmouse.generic.id        = ID_INVERTMOUSE;
   1471 	s_controls.invertmouse.generic.callback  = Controls_MenuEvent;
   1472 	s_controls.invertmouse.generic.statusbar = Controls_StatusBar;
   1473 
   1474 	s_controls.smoothmouse.generic.type      = MTYPE_RADIOBUTTON;
   1475 	s_controls.smoothmouse.generic.flags	 = QMF_SMALLFONT;
   1476 	s_controls.smoothmouse.generic.x	     = SCREEN_WIDTH/2;
   1477 	s_controls.smoothmouse.generic.name	     = "smooth mouse";
   1478 	s_controls.smoothmouse.generic.id        = ID_SMOOTHMOUSE;
   1479 	s_controls.smoothmouse.generic.callback  = Controls_MenuEvent;
   1480 	s_controls.smoothmouse.generic.statusbar = Controls_StatusBar;
   1481 
   1482 	s_controls.alwaysrun.generic.type      = MTYPE_RADIOBUTTON;
   1483 	s_controls.alwaysrun.generic.flags	   = QMF_SMALLFONT;
   1484 	s_controls.alwaysrun.generic.x	       = SCREEN_WIDTH/2;
   1485 	s_controls.alwaysrun.generic.name	   = "always run";
   1486 	s_controls.alwaysrun.generic.id        = ID_ALWAYSRUN;
   1487 	s_controls.alwaysrun.generic.callback  = Controls_MenuEvent;
   1488 	s_controls.alwaysrun.generic.statusbar = Controls_StatusBar;
   1489 
   1490 	s_controls.autoswitch.generic.type      = MTYPE_RADIOBUTTON;
   1491 	s_controls.autoswitch.generic.flags	    = QMF_SMALLFONT;
   1492 	s_controls.autoswitch.generic.x	        = SCREEN_WIDTH/2;
   1493 	s_controls.autoswitch.generic.name	    = "autoswitch weapons";
   1494 	s_controls.autoswitch.generic.id        = ID_AUTOSWITCH;
   1495 	s_controls.autoswitch.generic.callback  = Controls_MenuEvent;
   1496 	s_controls.autoswitch.generic.statusbar = Controls_StatusBar;
   1497 
   1498 	s_controls.sensitivity.generic.type	     = MTYPE_SLIDER;
   1499 	s_controls.sensitivity.generic.x		 = SCREEN_WIDTH/2;
   1500 	s_controls.sensitivity.generic.flags	 = QMF_SMALLFONT;
   1501 	s_controls.sensitivity.generic.name	     = "mouse speed";
   1502 	s_controls.sensitivity.generic.id 	     = ID_MOUSESPEED;
   1503 	s_controls.sensitivity.generic.callback  = Controls_MenuEvent;
   1504 	s_controls.sensitivity.minvalue		     = 2;
   1505 	s_controls.sensitivity.maxvalue		     = 30;
   1506 	s_controls.sensitivity.generic.statusbar = Controls_StatusBar;
   1507 
   1508 	s_controls.gesture.generic.type	     = MTYPE_ACTION;
   1509 	s_controls.gesture.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1510 	s_controls.gesture.generic.callback  = Controls_ActionEvent;
   1511 	s_controls.gesture.generic.ownerdraw = Controls_DrawKeyBinding;
   1512 	s_controls.gesture.generic.id        = ID_GESTURE;
   1513 
   1514 	s_controls.chat.generic.type	  = MTYPE_ACTION;
   1515 	s_controls.chat.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1516 	s_controls.chat.generic.callback  = Controls_ActionEvent;
   1517 	s_controls.chat.generic.ownerdraw = Controls_DrawKeyBinding;
   1518 	s_controls.chat.generic.id        = ID_CHAT;
   1519 
   1520 	s_controls.chat2.generic.type	   = MTYPE_ACTION;
   1521 	s_controls.chat2.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1522 	s_controls.chat2.generic.callback  = Controls_ActionEvent;
   1523 	s_controls.chat2.generic.ownerdraw = Controls_DrawKeyBinding;
   1524 	s_controls.chat2.generic.id        = ID_CHAT2;
   1525 
   1526 	s_controls.chat3.generic.type	   = MTYPE_ACTION;
   1527 	s_controls.chat3.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1528 	s_controls.chat3.generic.callback  = Controls_ActionEvent;
   1529 	s_controls.chat3.generic.ownerdraw = Controls_DrawKeyBinding;
   1530 	s_controls.chat3.generic.id        = ID_CHAT3;
   1531 
   1532 	s_controls.chat4.generic.type	   = MTYPE_ACTION;
   1533 	s_controls.chat4.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
   1534 	s_controls.chat4.generic.callback  = Controls_ActionEvent;
   1535 	s_controls.chat4.generic.ownerdraw = Controls_DrawKeyBinding;
   1536 	s_controls.chat4.generic.id        = ID_CHAT4;
   1537 
   1538 	s_controls.joyenable.generic.type      = MTYPE_RADIOBUTTON;
   1539 	s_controls.joyenable.generic.flags	   = QMF_SMALLFONT;
   1540 	s_controls.joyenable.generic.x	       = SCREEN_WIDTH/2;
   1541 	s_controls.joyenable.generic.name	   = "joystick";
   1542 	s_controls.joyenable.generic.id        = ID_JOYENABLE;
   1543 	s_controls.joyenable.generic.callback  = Controls_MenuEvent;
   1544 	s_controls.joyenable.generic.statusbar = Controls_StatusBar;
   1545 
   1546 	s_controls.joythreshold.generic.type	  = MTYPE_SLIDER;
   1547 	s_controls.joythreshold.generic.x		  = SCREEN_WIDTH/2;
   1548 	s_controls.joythreshold.generic.flags	  = QMF_SMALLFONT;
   1549 	s_controls.joythreshold.generic.name	  = "joystick threshold";
   1550 	s_controls.joythreshold.generic.id 	      = ID_JOYTHRESHOLD;
   1551 	s_controls.joythreshold.generic.callback  = Controls_MenuEvent;
   1552 	s_controls.joythreshold.minvalue		  = 0.05f;
   1553 	s_controls.joythreshold.maxvalue		  = 0.75f;
   1554 	s_controls.joythreshold.generic.statusbar = Controls_StatusBar;
   1555 
   1556 	s_controls.name.generic.type	= MTYPE_PTEXT;
   1557 	s_controls.name.generic.flags	= QMF_CENTER_JUSTIFY|QMF_INACTIVE;
   1558 	s_controls.name.generic.x		= 320;
   1559 	s_controls.name.generic.y		= 440;
   1560 	s_controls.name.string			= playername;
   1561 	s_controls.name.style			= UI_CENTER;
   1562 	s_controls.name.color			= text_color_normal;
   1563 
   1564 	Menu_AddItem( &s_controls.menu, &s_controls.banner );
   1565 	Menu_AddItem( &s_controls.menu, &s_controls.framel );
   1566 	Menu_AddItem( &s_controls.menu, &s_controls.framer );
   1567 	Menu_AddItem( &s_controls.menu, &s_controls.player );
   1568 	Menu_AddItem( &s_controls.menu, &s_controls.name );
   1569 
   1570 	Menu_AddItem( &s_controls.menu, &s_controls.looking );
   1571 	Menu_AddItem( &s_controls.menu, &s_controls.movement );
   1572 	Menu_AddItem( &s_controls.menu, &s_controls.weapons );
   1573 	Menu_AddItem( &s_controls.menu, &s_controls.misc );
   1574 
   1575 	Menu_AddItem( &s_controls.menu, &s_controls.sensitivity );
   1576 	Menu_AddItem( &s_controls.menu, &s_controls.smoothmouse );
   1577 	Menu_AddItem( &s_controls.menu, &s_controls.invertmouse );
   1578 	Menu_AddItem( &s_controls.menu, &s_controls.lookup );
   1579 	Menu_AddItem( &s_controls.menu, &s_controls.lookdown );
   1580 	Menu_AddItem( &s_controls.menu, &s_controls.mouselook );
   1581 	Menu_AddItem( &s_controls.menu, &s_controls.freelook );
   1582 	Menu_AddItem( &s_controls.menu, &s_controls.centerview );
   1583 	Menu_AddItem( &s_controls.menu, &s_controls.zoomview );
   1584 	Menu_AddItem( &s_controls.menu, &s_controls.joyenable );
   1585 	Menu_AddItem( &s_controls.menu, &s_controls.joythreshold );
   1586 
   1587 	Menu_AddItem( &s_controls.menu, &s_controls.alwaysrun );
   1588 	Menu_AddItem( &s_controls.menu, &s_controls.run );
   1589 	Menu_AddItem( &s_controls.menu, &s_controls.walkforward );
   1590 	Menu_AddItem( &s_controls.menu, &s_controls.backpedal );
   1591 	Menu_AddItem( &s_controls.menu, &s_controls.stepleft );
   1592 	Menu_AddItem( &s_controls.menu, &s_controls.stepright );
   1593 	Menu_AddItem( &s_controls.menu, &s_controls.moveup );
   1594 	Menu_AddItem( &s_controls.menu, &s_controls.movedown );
   1595 	Menu_AddItem( &s_controls.menu, &s_controls.turnleft );
   1596 	Menu_AddItem( &s_controls.menu, &s_controls.turnright );
   1597 	Menu_AddItem( &s_controls.menu, &s_controls.sidestep );
   1598 
   1599 	Menu_AddItem( &s_controls.menu, &s_controls.attack );
   1600 	Menu_AddItem( &s_controls.menu, &s_controls.nextweapon );
   1601 	Menu_AddItem( &s_controls.menu, &s_controls.prevweapon );
   1602 	Menu_AddItem( &s_controls.menu, &s_controls.autoswitch );
   1603 	Menu_AddItem( &s_controls.menu, &s_controls.chainsaw );
   1604 	Menu_AddItem( &s_controls.menu, &s_controls.machinegun );
   1605 	Menu_AddItem( &s_controls.menu, &s_controls.shotgun );
   1606 	Menu_AddItem( &s_controls.menu, &s_controls.grenadelauncher );
   1607 	Menu_AddItem( &s_controls.menu, &s_controls.rocketlauncher );
   1608 	Menu_AddItem( &s_controls.menu, &s_controls.lightning );
   1609 	Menu_AddItem( &s_controls.menu, &s_controls.railgun );
   1610 	Menu_AddItem( &s_controls.menu, &s_controls.plasma );
   1611 	Menu_AddItem( &s_controls.menu, &s_controls.bfg );
   1612 
   1613 	Menu_AddItem( &s_controls.menu, &s_controls.showscores );
   1614 	Menu_AddItem( &s_controls.menu, &s_controls.useitem );
   1615 	Menu_AddItem( &s_controls.menu, &s_controls.gesture );
   1616 	Menu_AddItem( &s_controls.menu, &s_controls.chat );
   1617 	Menu_AddItem( &s_controls.menu, &s_controls.chat2 );
   1618 	Menu_AddItem( &s_controls.menu, &s_controls.chat3 );
   1619 	Menu_AddItem( &s_controls.menu, &s_controls.chat4 );
   1620 
   1621 	Menu_AddItem( &s_controls.menu, &s_controls.back );
   1622 
   1623 	trap_Cvar_VariableStringBuffer( "name", s_controls.name.string, 16 );
   1624 	Q_CleanStr( s_controls.name.string );
   1625 
   1626 	// initialize the configurable cvars
   1627 	Controls_InitCvars();
   1628 
   1629 	// initialize the current config
   1630 	Controls_GetConfig();
   1631 
   1632 	// intialize the model
   1633 	Controls_InitModel();
   1634 
   1635 	// intialize the weapons
   1636 	Controls_InitWeapons ();
   1637 
   1638 	// initial default section
   1639 	s_controls.section = C_LOOKING;
   1640 
   1641 	// update the ui
   1642 	Controls_Update();
   1643 }
   1644 
   1645 
   1646 /*
   1647 =================
   1648 Controls_Cache
   1649 =================
   1650 */
   1651 void Controls_Cache( void ) {
   1652 	trap_R_RegisterShaderNoMip( ART_BACK0 );
   1653 	trap_R_RegisterShaderNoMip( ART_BACK1 );
   1654 	trap_R_RegisterShaderNoMip( ART_FRAMEL );
   1655 	trap_R_RegisterShaderNoMip( ART_FRAMER );
   1656 }
   1657 
   1658 
   1659 /*
   1660 =================
   1661 UI_ControlsMenu
   1662 =================
   1663 */
   1664 void UI_ControlsMenu( void ) {
   1665 	Controls_MenuInit();
   1666 	UI_PushMenu( &s_controls.menu );
   1667 }