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 Quake III Arena source code; 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};
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 */
Controls_InitCvars(void)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 */
Controls_GetCvarDefault(char * name)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 */
Controls_GetCvarValue(char * name)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 */
Controls_UpdateModel(int anim)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 */
Controls_Update(void)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 		for( j = 0;  (control = controls[j]) ; j++ ) {
565 			control->flags |= (QMF_HIDDEN|QMF_INACTIVE);
566 		}
567 	}
568 
569 	controls = g_controls[s_controls.section];
570 
571 	// enable controls in active group (and count number of items for vertical centering)
572 	for( j = 0;  (control = controls[j]) ; j++ ) {
573 		control->flags &= ~(QMF_GRAYED|QMF_HIDDEN|QMF_INACTIVE);
574 	}
575 
576 	// position controls
577 	y = ( SCREEN_HEIGHT - j * SMALLCHAR_HEIGHT ) / 2;
578 	for( j = 0;	(control = controls[j]) ; j++, y += SMALLCHAR_HEIGHT ) {
579 		control->x      = 320;
580 		control->y      = y;
581 		control->left   = 320 - 19*SMALLCHAR_WIDTH;
582 		control->right  = 320 + 21*SMALLCHAR_WIDTH;
583 		control->top    = y;
584 		control->bottom = y + SMALLCHAR_HEIGHT;
585 	}
586 
587 	if( s_controls.waitingforkey ) {
588 		// disable everybody
589 		for( i = 0; i < s_controls.menu.nitems; i++ ) {
590 			((menucommon_s*)(s_controls.menu.items[i]))->flags |= QMF_GRAYED;
591 		}
592 
593 		// enable action item
594 		((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->flags &= ~QMF_GRAYED;
595 
596 		// don't gray out player's name
597 		s_controls.name.generic.flags &= ~QMF_GRAYED;
598 
599 		return;
600 	}
601 
602 	// enable everybody
603 	for( i = 0; i < s_controls.menu.nitems; i++ ) {
604 		((menucommon_s*)(s_controls.menu.items[i]))->flags &= ~QMF_GRAYED;
605 	}
606 
607 	// makes sure flags are right on the group selection controls
608 	s_controls.looking.generic.flags  &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
609 	s_controls.movement.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
610 	s_controls.weapons.generic.flags  &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
611 	s_controls.misc.generic.flags     &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
612 
613 	s_controls.looking.generic.flags  |= QMF_PULSEIFFOCUS;
614 	s_controls.movement.generic.flags |= QMF_PULSEIFFOCUS;
615 	s_controls.weapons.generic.flags  |= QMF_PULSEIFFOCUS;
616 	s_controls.misc.generic.flags     |= QMF_PULSEIFFOCUS;
617 
618 	// set buttons
619 	switch( s_controls.section ) {
620 	case C_MOVEMENT:
621 		s_controls.movement.generic.flags &= ~QMF_PULSEIFFOCUS;
622 		s_controls.movement.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
623 		break;
624 
625 	case C_LOOKING:
626 		s_controls.looking.generic.flags &= ~QMF_PULSEIFFOCUS;
627 		s_controls.looking.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
628 		break;
629 
630 	case C_WEAPONS:
631 		s_controls.weapons.generic.flags &= ~QMF_PULSEIFFOCUS;
632 		s_controls.weapons.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
633 		break;
634 
635 	case C_MISC:
636 		s_controls.misc.generic.flags &= ~QMF_PULSEIFFOCUS;
637 		s_controls.misc.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
638 		break;
639 	}
640 }
641 
642 
643 /*
644 =================
645 Controls_DrawKeyBinding
646 =================
647 */
Controls_DrawKeyBinding(void * self)648 static void Controls_DrawKeyBinding( void *self )
649 {
650 	menuaction_s*	a;
651 	int				x;
652 	int				y;
653 	int				b1;
654 	int				b2;
655 	qboolean		c;
656 	char			name[32];
657 	char			name2[32];
658 
659 	a = (menuaction_s*) self;
660 
661 	x =	a->generic.x;
662 	y = a->generic.y;
663 
664 	c = (Menu_ItemAtCursor( a->generic.parent ) == a);
665 
666 	b1 = g_bindings[a->generic.id].bind1;
667 	if (b1 == -1)
668 		strcpy(name,"???");
669 	else
670 	{
671 		trap_Key_KeynumToStringBuf( b1, name, 32 );
672 		Q_strupr(name);
673 
674 		b2 = g_bindings[a->generic.id].bind2;
675 		if (b2 != -1)
676 		{
677 			trap_Key_KeynumToStringBuf( b2, name2, 32 );
678 			Q_strupr(name2);
679 
680 			strcat( name, " or " );
681 			strcat( name, name2 );
682 		}
683 	}
684 
685 	if (c)
686 	{
687 		UI_FillRect( a->generic.left, a->generic.top, a->generic.right-a->generic.left+1, a->generic.bottom-a->generic.top+1, listbar_color );
688 
689 		UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_highlight );
690 		UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT|UI_PULSE, text_color_highlight );
691 
692 		if (s_controls.waitingforkey)
693 		{
694 			UI_DrawChar( x, y, '=', UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight);
695 			UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Waiting for new key ... ESCAPE to cancel", UI_SMALLFONT|UI_CENTER|UI_PULSE, colorWhite );
696 		}
697 		else
698 		{
699 			UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight);
700 			UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.78, "Press ENTER or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite );
701 			UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.82, "Press BACKSPACE to clear", UI_SMALLFONT|UI_CENTER, colorWhite );
702 		}
703 	}
704 	else
705 	{
706 		if (a->generic.flags & QMF_GRAYED)
707 		{
708 			UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_disabled );
709 			UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, text_color_disabled );
710 		}
711 		else
712 		{
713 			UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, controls_binding_color );
714 			UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, controls_binding_color );
715 		}
716 	}
717 }
718 
719 /*
720 =================
721 Controls_StatusBar
722 =================
723 */
Controls_StatusBar(void * self)724 static void Controls_StatusBar( void *self )
725 {
726 	UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Use Arrow Keys or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite );
727 }
728 
729 
730 /*
731 =================
732 Controls_DrawPlayer
733 =================
734 */
Controls_DrawPlayer(void * self)735 static void Controls_DrawPlayer( void *self ) {
736 	menubitmap_s	*b;
737 	char			buf[MAX_QPATH];
738 
739 	trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) );
740 	if ( strcmp( buf, s_controls.playerModel ) != 0 ) {
741 		UI_PlayerInfo_SetModel( &s_controls.playerinfo, buf );
742 		strcpy( s_controls.playerModel, buf );
743 		Controls_UpdateModel( ANIM_IDLE );
744 	}
745 
746 	b = (menubitmap_s*) self;
747 	UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_controls.playerinfo, uis.realtime/2 );
748 }
749 
750 
751 /*
752 =================
753 Controls_GetKeyAssignment
754 =================
755 */
Controls_GetKeyAssignment(char * command,int * twokeys)756 static void Controls_GetKeyAssignment (char *command, int *twokeys)
757 {
758 	int		count;
759 	int		j;
760 	char	b[256];
761 
762 	twokeys[0] = twokeys[1] = -1;
763 	count = 0;
764 
765 	for ( j = 0; j < 256; j++ )
766 	{
767 		trap_Key_GetBindingBuf( j, b, 256 );
768 		if ( *b == 0 ) {
769 			continue;
770 		}
771 		if ( !Q_stricmp( b, command ) ) {
772 			twokeys[count] = j;
773 			count++;
774 			if (count == 2)
775 				break;
776 		}
777 	}
778 }
779 
780 /*
781 =================
782 Controls_GetConfig
783 =================
784 */
Controls_GetConfig(void)785 static void Controls_GetConfig( void )
786 {
787 	int		i;
788 	int		twokeys[2];
789 	bind_t*	bindptr;
790 
791 	// put the bindings into a local store
792 	bindptr = g_bindings;
793 
794 	// iterate each command, get its numeric binding
795 	for (i=0; ;i++,bindptr++)
796 	{
797 		if (!bindptr->label)
798 			break;
799 
800 		Controls_GetKeyAssignment(bindptr->command, twokeys);
801 
802 		bindptr->bind1 = twokeys[0];
803 		bindptr->bind2 = twokeys[1];
804 	}
805 
806 	s_controls.invertmouse.curvalue  = Controls_GetCvarValue( "m_pitch" ) < 0;
807 	s_controls.smoothmouse.curvalue  = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "m_filter" ) );
808 	s_controls.alwaysrun.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_run" ) );
809 	s_controls.autoswitch.curvalue   = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cg_autoswitch" ) );
810 	s_controls.sensitivity.curvalue  = UI_ClampCvar( 2, 30, Controls_GetCvarValue( "sensitivity" ) );
811 	s_controls.joyenable.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "in_joystick" ) );
812 	s_controls.joythreshold.curvalue = UI_ClampCvar( 0.05f, 0.75f, Controls_GetCvarValue( "joy_threshold" ) );
813 	s_controls.freelook.curvalue     = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_freelook" ) );
814 }
815 
816 /*
817 =================
818 Controls_SetConfig
819 =================
820 */
Controls_SetConfig(void)821 static void Controls_SetConfig( void )
822 {
823 	int		i;
824 	bind_t*	bindptr;
825 
826 	// set the bindings from the local store
827 	bindptr = g_bindings;
828 
829 	// iterate each command, get its numeric binding
830 	for (i=0; ;i++,bindptr++)
831 	{
832 		if (!bindptr->label)
833 			break;
834 
835 		if (bindptr->bind1 != -1)
836 		{
837 			trap_Key_SetBinding( bindptr->bind1, bindptr->command );
838 
839 			if (bindptr->bind2 != -1)
840 				trap_Key_SetBinding( bindptr->bind2, bindptr->command );
841 		}
842 	}
843 
844 	if ( s_controls.invertmouse.curvalue )
845 		trap_Cvar_SetValue( "m_pitch", -fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
846 	else
847 		trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
848 
849 	trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue );
850 	trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue );
851 	trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue );
852 	trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue );
853 	trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue );
854 	trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue );
855 	trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue );
856 	trap_Cmd_ExecuteText( EXEC_APPEND, "in_restart\n" );
857 }
858 
859 /*
860 =================
861 Controls_SetDefaults
862 =================
863 */
Controls_SetDefaults(void)864 static void Controls_SetDefaults( void )
865 {
866 	int	i;
867 	bind_t*	bindptr;
868 
869 	// set the bindings from the local store
870 	bindptr = g_bindings;
871 
872 	// iterate each command, set its default binding
873 	for (i=0; ;i++,bindptr++)
874 	{
875 		if (!bindptr->label)
876 			break;
877 
878 		bindptr->bind1 = bindptr->defaultbind1;
879 		bindptr->bind2 = bindptr->defaultbind2;
880 	}
881 
882 	s_controls.invertmouse.curvalue  = Controls_GetCvarDefault( "m_pitch" ) < 0;
883 	s_controls.smoothmouse.curvalue  = Controls_GetCvarDefault( "m_filter" );
884 	s_controls.alwaysrun.curvalue    = Controls_GetCvarDefault( "cl_run" );
885 	s_controls.autoswitch.curvalue   = Controls_GetCvarDefault( "cg_autoswitch" );
886 	s_controls.sensitivity.curvalue  = Controls_GetCvarDefault( "sensitivity" );
887 	s_controls.joyenable.curvalue    = Controls_GetCvarDefault( "in_joystick" );
888 	s_controls.joythreshold.curvalue = Controls_GetCvarDefault( "joy_threshold" );
889 	s_controls.freelook.curvalue     = Controls_GetCvarDefault( "cl_freelook" );
890 }
891 
892 /*
893 =================
894 Controls_MenuKey
895 =================
896 */
Controls_MenuKey(int key)897 static sfxHandle_t Controls_MenuKey( int key )
898 {
899 	int			id;
900 	int			i;
901 	qboolean	found;
902 	bind_t*		bindptr;
903 	found = qfalse;
904 
905 	if (!s_controls.waitingforkey)
906 	{
907 		switch (key)
908 		{
909 			case K_BACKSPACE:
910 			case K_DEL:
911 			case K_KP_DEL:
912 				key = -1;
913 				break;
914 
915 			case K_MOUSE2:
916 			case K_ESCAPE:
917 				if (s_controls.changesmade)
918 					Controls_SetConfig();
919 				goto ignorekey;
920 
921 			default:
922 				goto ignorekey;
923 		}
924 	}
925 	else
926 	{
927 		if (key & K_CHAR_FLAG)
928 			goto ignorekey;
929 
930 		switch (key)
931 		{
932 			case K_ESCAPE:
933 				s_controls.waitingforkey = qfalse;
934 				Controls_Update();
935 				return (menu_out_sound);
936 
937 			case '`':
938 				goto ignorekey;
939 		}
940 	}
941 
942 	s_controls.changesmade = qtrue;
943 
944 	if (key != -1)
945 	{
946 		// remove from any other bind
947 		bindptr = g_bindings;
948 		for (i=0; ;i++,bindptr++)
949 		{
950 			if (!bindptr->label)
951 				break;
952 
953 			if (bindptr->bind2 == key)
954 				bindptr->bind2 = -1;
955 
956 			if (bindptr->bind1 == key)
957 			{
958 				bindptr->bind1 = bindptr->bind2;
959 				bindptr->bind2 = -1;
960 			}
961 		}
962 	}
963 
964 	// assign key to local store
965 	id      = ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->id;
966 	bindptr = g_bindings;
967 	for (i=0; ;i++,bindptr++)
968 	{
969 		if (!bindptr->label)
970 			break;
971 
972 		if (bindptr->id == id)
973 		{
974 			found = qtrue;
975 			if (key == -1)
976 			{
977 				if( bindptr->bind1 != -1 ) {
978 					trap_Key_SetBinding( bindptr->bind1, "" );
979 					bindptr->bind1 = -1;
980 				}
981 				if( bindptr->bind2 != -1 ) {
982 					trap_Key_SetBinding( bindptr->bind2, "" );
983 					bindptr->bind2 = -1;
984 				}
985 			}
986 			else if (bindptr->bind1 == -1) {
987 				bindptr->bind1 = key;
988 			}
989 			else if (bindptr->bind1 != key && bindptr->bind2 == -1) {
990 				bindptr->bind2 = key;
991 			}
992 			else
993 			{
994 				trap_Key_SetBinding( bindptr->bind1, "" );
995 				trap_Key_SetBinding( bindptr->bind2, "" );
996 				bindptr->bind1 = key;
997 				bindptr->bind2 = -1;
998 			}
999 			break;
1000 		}
1001 	}
1002 
1003 	s_controls.waitingforkey = qfalse;
1004 
1005 	if (found)
1006 	{
1007 		Controls_Update();
1008 		return (menu_out_sound);
1009 	}
1010 
1011 ignorekey:
1012 	return Menu_DefaultKey( &s_controls.menu, key );
1013 }
1014 
1015 /*
1016 =================
1017 Controls_ResetDefaults_Action
1018 =================
1019 */
Controls_ResetDefaults_Action(qboolean result)1020 static void Controls_ResetDefaults_Action( qboolean result ) {
1021 	if( !result ) {
1022 		return;
1023 	}
1024 
1025 	s_controls.changesmade = qtrue;
1026 	Controls_SetDefaults();
1027 	Controls_Update();
1028 }
1029 
1030 /*
1031 =================
1032 Controls_ResetDefaults_Draw
1033 =================
1034 */
Controls_ResetDefaults_Draw(void)1035 static void Controls_ResetDefaults_Draw( void ) {
1036 	UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This will reset all", UI_CENTER|UI_SMALLFONT, color_yellow );
1037 	UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "controls to their default values.", UI_CENTER|UI_SMALLFONT, color_yellow );
1038 }
1039 
1040 /*
1041 =================
1042 Controls_MenuEvent
1043 =================
1044 */
Controls_MenuEvent(void * ptr,int event)1045 static void Controls_MenuEvent( void* ptr, int event )
1046 {
1047 	switch (((menucommon_s*)ptr)->id)
1048 	{
1049 		case ID_MOVEMENT:
1050 			if (event == QM_ACTIVATED)
1051 			{
1052 				s_controls.section = C_MOVEMENT;
1053 				Controls_Update();
1054 			}
1055 			break;
1056 
1057 		case ID_LOOKING:
1058 			if (event == QM_ACTIVATED)
1059 			{
1060 				s_controls.section = C_LOOKING;
1061 				Controls_Update();
1062 			}
1063 			break;
1064 
1065 		case ID_WEAPONS:
1066 			if (event == QM_ACTIVATED)
1067 			{
1068 				s_controls.section = C_WEAPONS;
1069 				Controls_Update();
1070 			}
1071 			break;
1072 
1073 		case ID_MISC:
1074 			if (event == QM_ACTIVATED)
1075 			{
1076 				s_controls.section = C_MISC;
1077 				Controls_Update();
1078 			}
1079 			break;
1080 
1081 		case ID_DEFAULTS:
1082 			if (event == QM_ACTIVATED)
1083 			{
1084 				UI_ConfirmMenu( "SET TO DEFAULTS?", Controls_ResetDefaults_Draw, Controls_ResetDefaults_Action );
1085 			}
1086 			break;
1087 
1088 		case ID_BACK:
1089 			if (event == QM_ACTIVATED)
1090 			{
1091 				if (s_controls.changesmade)
1092 					Controls_SetConfig();
1093 				UI_PopMenu();
1094 			}
1095 			break;
1096 
1097 		case ID_SAVEANDEXIT:
1098 			if (event == QM_ACTIVATED)
1099 			{
1100 				Controls_SetConfig();
1101 				UI_PopMenu();
1102 			}
1103 			break;
1104 
1105 		case ID_EXIT:
1106 			if (event == QM_ACTIVATED)
1107 			{
1108 				UI_PopMenu();
1109 			}
1110 			break;
1111 
1112 		case ID_FREELOOK:
1113 		case ID_MOUSESPEED:
1114 		case ID_INVERTMOUSE:
1115 		case ID_SMOOTHMOUSE:
1116 		case ID_ALWAYSRUN:
1117 		case ID_AUTOSWITCH:
1118 		case ID_JOYENABLE:
1119 		case ID_JOYTHRESHOLD:
1120 			if (event == QM_ACTIVATED)
1121 			{
1122 				s_controls.changesmade = qtrue;
1123 			}
1124 			break;
1125 	}
1126 }
1127 
1128 /*
1129 =================
1130 Controls_ActionEvent
1131 =================
1132 */
Controls_ActionEvent(void * ptr,int event)1133 static void Controls_ActionEvent( void* ptr, int event )
1134 {
1135 	if (event == QM_LOSTFOCUS)
1136 	{
1137 		Controls_UpdateModel( ANIM_IDLE );
1138 	}
1139 	else if (event == QM_GOTFOCUS)
1140 	{
1141 		Controls_UpdateModel( g_bindings[((menucommon_s*)ptr)->id].anim );
1142 	}
1143 	else if ((event == QM_ACTIVATED) && !s_controls.waitingforkey)
1144 	{
1145 		s_controls.waitingforkey = 1;
1146 		Controls_Update();
1147 	}
1148 }
1149 
1150 /*
1151 =================
1152 Controls_InitModel
1153 =================
1154 */
Controls_InitModel(void)1155 static void Controls_InitModel( void )
1156 {
1157 	memset( &s_controls.playerinfo, 0, sizeof(playerInfo_t) );
1158 
1159 	UI_PlayerInfo_SetModel( &s_controls.playerinfo, UI_Cvar_VariableString( "model" ) );
1160 
1161 	Controls_UpdateModel( ANIM_IDLE );
1162 }
1163 
1164 /*
1165 =================
1166 Controls_InitWeapons
1167 =================
1168 */
Controls_InitWeapons(void)1169 static void Controls_InitWeapons( void ) {
1170 	gitem_t *	item;
1171 
1172 	for ( item = bg_itemlist + 1 ; item->classname ; item++ ) {
1173 		if ( item->giType != IT_WEAPON ) {
1174 			continue;
1175 		}
1176 		trap_R_RegisterModel( item->world_model[0] );
1177 	}
1178 }
1179 
1180 /*
1181 =================
1182 Controls_MenuInit
1183 =================
1184 */
Controls_MenuInit(void)1185 static void Controls_MenuInit( void )
1186 {
1187 	static char playername[32];
1188 
1189 	// zero set all our globals
1190 	memset( &s_controls, 0 ,sizeof(controls_t) );
1191 
1192 	Controls_Cache();
1193 
1194 	s_controls.menu.key        = Controls_MenuKey;
1195 	s_controls.menu.wrapAround = qtrue;
1196 	s_controls.menu.fullscreen = qtrue;
1197 
1198 	s_controls.banner.generic.type	= MTYPE_BTEXT;
1199 	s_controls.banner.generic.flags	= QMF_CENTER_JUSTIFY;
1200 	s_controls.banner.generic.x		= 320;
1201 	s_controls.banner.generic.y		= 16;
1202 	s_controls.banner.string		= "CONTROLS";
1203 	s_controls.banner.color			= color_white;
1204 	s_controls.banner.style			= UI_CENTER;
1205 
1206 	s_controls.framel.generic.type  = MTYPE_BITMAP;
1207 	s_controls.framel.generic.name  = ART_FRAMEL;
1208 	s_controls.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
1209 	s_controls.framel.generic.x     = 0;
1210 	s_controls.framel.generic.y     = 78;
1211 	s_controls.framel.width  	    = 256;
1212 	s_controls.framel.height  	    = 329;
1213 
1214 	s_controls.framer.generic.type  = MTYPE_BITMAP;
1215 	s_controls.framer.generic.name  = ART_FRAMER;
1216 	s_controls.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
1217 	s_controls.framer.generic.x     = 376;
1218 	s_controls.framer.generic.y     = 76;
1219 	s_controls.framer.width  	    = 256;
1220 	s_controls.framer.height  	    = 334;
1221 
1222 	s_controls.looking.generic.type     = MTYPE_PTEXT;
1223 	s_controls.looking.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
1224 	s_controls.looking.generic.id	    = ID_LOOKING;
1225 	s_controls.looking.generic.callback	= Controls_MenuEvent;
1226 	s_controls.looking.generic.x	    = 152;
1227 	s_controls.looking.generic.y	    = 240 - 2 * PROP_HEIGHT;
1228 	s_controls.looking.string			= "LOOK";
1229 	s_controls.looking.style			= UI_RIGHT;
1230 	s_controls.looking.color			= color_red;
1231 
1232 	s_controls.movement.generic.type     = MTYPE_PTEXT;
1233 	s_controls.movement.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
1234 	s_controls.movement.generic.id	     = ID_MOVEMENT;
1235 	s_controls.movement.generic.callback = Controls_MenuEvent;
1236 	s_controls.movement.generic.x	     = 152;
1237 	s_controls.movement.generic.y	     = 240 - PROP_HEIGHT;
1238 	s_controls.movement.string			= "MOVE";
1239 	s_controls.movement.style			= UI_RIGHT;
1240 	s_controls.movement.color			= color_red;
1241 
1242 	s_controls.weapons.generic.type	    = MTYPE_PTEXT;
1243 	s_controls.weapons.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
1244 	s_controls.weapons.generic.id	    = ID_WEAPONS;
1245 	s_controls.weapons.generic.callback	= Controls_MenuEvent;
1246 	s_controls.weapons.generic.x	    = 152;
1247 	s_controls.weapons.generic.y	    = 240;
1248 	s_controls.weapons.string			= "SHOOT";
1249 	s_controls.weapons.style			= UI_RIGHT;
1250 	s_controls.weapons.color			= color_red;
1251 
1252 	s_controls.misc.generic.type	 = MTYPE_PTEXT;
1253 	s_controls.misc.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
1254 	s_controls.misc.generic.id	     = ID_MISC;
1255 	s_controls.misc.generic.callback = Controls_MenuEvent;
1256 	s_controls.misc.generic.x		 = 152;
1257 	s_controls.misc.generic.y		 = 240 + PROP_HEIGHT;
1258 	s_controls.misc.string			= "MISC";
1259 	s_controls.misc.style			= UI_RIGHT;
1260 	s_controls.misc.color			= color_red;
1261 
1262 	s_controls.back.generic.type	 = MTYPE_BITMAP;
1263 	s_controls.back.generic.name     = ART_BACK0;
1264 	s_controls.back.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
1265 	s_controls.back.generic.x		 = 0;
1266 	s_controls.back.generic.y		 = 480-64;
1267 	s_controls.back.generic.id	     = ID_BACK;
1268 	s_controls.back.generic.callback = Controls_MenuEvent;
1269 	s_controls.back.width  		     = 128;
1270 	s_controls.back.height  		 = 64;
1271 	s_controls.back.focuspic         = ART_BACK1;
1272 
1273 	s_controls.player.generic.type      = MTYPE_BITMAP;
1274 	s_controls.player.generic.flags     = QMF_INACTIVE;
1275 	s_controls.player.generic.ownerdraw = Controls_DrawPlayer;
1276 	s_controls.player.generic.x	        = 400;
1277 	s_controls.player.generic.y	        = -40;
1278 	s_controls.player.width	            = 32*10;
1279 	s_controls.player.height            = 56*10;
1280 
1281 	s_controls.walkforward.generic.type	     = MTYPE_ACTION;
1282 	s_controls.walkforward.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1283 	s_controls.walkforward.generic.callback  = Controls_ActionEvent;
1284 	s_controls.walkforward.generic.ownerdraw = Controls_DrawKeyBinding;
1285 	s_controls.walkforward.generic.id 	     = ID_FORWARD;
1286 
1287 	s_controls.backpedal.generic.type	   = MTYPE_ACTION;
1288 	s_controls.backpedal.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1289 	s_controls.backpedal.generic.callback  = Controls_ActionEvent;
1290 	s_controls.backpedal.generic.ownerdraw = Controls_DrawKeyBinding;
1291 	s_controls.backpedal.generic.id 	   = ID_BACKPEDAL;
1292 
1293 	s_controls.stepleft.generic.type	  = MTYPE_ACTION;
1294 	s_controls.stepleft.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1295 	s_controls.stepleft.generic.callback  = Controls_ActionEvent;
1296 	s_controls.stepleft.generic.ownerdraw = Controls_DrawKeyBinding;
1297 	s_controls.stepleft.generic.id 		  = ID_MOVELEFT;
1298 
1299 	s_controls.stepright.generic.type	   = MTYPE_ACTION;
1300 	s_controls.stepright.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1301 	s_controls.stepright.generic.callback  = Controls_ActionEvent;
1302 	s_controls.stepright.generic.ownerdraw = Controls_DrawKeyBinding;
1303 	s_controls.stepright.generic.id        = ID_MOVERIGHT;
1304 
1305 	s_controls.moveup.generic.type	    = MTYPE_ACTION;
1306 	s_controls.moveup.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1307 	s_controls.moveup.generic.callback  = Controls_ActionEvent;
1308 	s_controls.moveup.generic.ownerdraw = Controls_DrawKeyBinding;
1309 	s_controls.moveup.generic.id        = ID_MOVEUP;
1310 
1311 	s_controls.movedown.generic.type	  = MTYPE_ACTION;
1312 	s_controls.movedown.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1313 	s_controls.movedown.generic.callback  = Controls_ActionEvent;
1314 	s_controls.movedown.generic.ownerdraw = Controls_DrawKeyBinding;
1315 	s_controls.movedown.generic.id        = ID_MOVEDOWN;
1316 
1317 	s_controls.turnleft.generic.type	  = MTYPE_ACTION;
1318 	s_controls.turnleft.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1319 	s_controls.turnleft.generic.callback  = Controls_ActionEvent;
1320 	s_controls.turnleft.generic.ownerdraw = Controls_DrawKeyBinding;
1321 	s_controls.turnleft.generic.id        = ID_LEFT;
1322 
1323 	s_controls.turnright.generic.type	   = MTYPE_ACTION;
1324 	s_controls.turnright.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1325 	s_controls.turnright.generic.callback  = Controls_ActionEvent;
1326 	s_controls.turnright.generic.ownerdraw = Controls_DrawKeyBinding;
1327 	s_controls.turnright.generic.id        = ID_RIGHT;
1328 
1329 	s_controls.sidestep.generic.type	  = MTYPE_ACTION;
1330 	s_controls.sidestep.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1331 	s_controls.sidestep.generic.callback  = Controls_ActionEvent;
1332 	s_controls.sidestep.generic.ownerdraw = Controls_DrawKeyBinding;
1333 	s_controls.sidestep.generic.id        = ID_STRAFE;
1334 
1335 	s_controls.run.generic.type	     = MTYPE_ACTION;
1336 	s_controls.run.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1337 	s_controls.run.generic.callback  = Controls_ActionEvent;
1338 	s_controls.run.generic.ownerdraw = Controls_DrawKeyBinding;
1339 	s_controls.run.generic.id        = ID_SPEED;
1340 
1341 	s_controls.chainsaw.generic.type	  = MTYPE_ACTION;
1342 	s_controls.chainsaw.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1343 	s_controls.chainsaw.generic.callback  = Controls_ActionEvent;
1344 	s_controls.chainsaw.generic.ownerdraw = Controls_DrawKeyBinding;
1345 	s_controls.chainsaw.generic.id        = ID_WEAPON1;
1346 
1347 	s_controls.machinegun.generic.type	    = MTYPE_ACTION;
1348 	s_controls.machinegun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1349 	s_controls.machinegun.generic.callback  = Controls_ActionEvent;
1350 	s_controls.machinegun.generic.ownerdraw = Controls_DrawKeyBinding;
1351 	s_controls.machinegun.generic.id        = ID_WEAPON2;
1352 
1353 	s_controls.shotgun.generic.type	     = MTYPE_ACTION;
1354 	s_controls.shotgun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1355 	s_controls.shotgun.generic.callback  = Controls_ActionEvent;
1356 	s_controls.shotgun.generic.ownerdraw = Controls_DrawKeyBinding;
1357 	s_controls.shotgun.generic.id        = ID_WEAPON3;
1358 
1359 	s_controls.grenadelauncher.generic.type	     = MTYPE_ACTION;
1360 	s_controls.grenadelauncher.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1361 	s_controls.grenadelauncher.generic.callback  = Controls_ActionEvent;
1362 	s_controls.grenadelauncher.generic.ownerdraw = Controls_DrawKeyBinding;
1363 	s_controls.grenadelauncher.generic.id        = ID_WEAPON4;
1364 
1365 	s_controls.rocketlauncher.generic.type	    = MTYPE_ACTION;
1366 	s_controls.rocketlauncher.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1367 	s_controls.rocketlauncher.generic.callback  = Controls_ActionEvent;
1368 	s_controls.rocketlauncher.generic.ownerdraw = Controls_DrawKeyBinding;
1369 	s_controls.rocketlauncher.generic.id        = ID_WEAPON5;
1370 
1371 	s_controls.lightning.generic.type	   = MTYPE_ACTION;
1372 	s_controls.lightning.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1373 	s_controls.lightning.generic.callback  = Controls_ActionEvent;
1374 	s_controls.lightning.generic.ownerdraw = Controls_DrawKeyBinding;
1375 	s_controls.lightning.generic.id        = ID_WEAPON6;
1376 
1377 	s_controls.railgun.generic.type	     = MTYPE_ACTION;
1378 	s_controls.railgun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1379 	s_controls.railgun.generic.callback  = Controls_ActionEvent;
1380 	s_controls.railgun.generic.ownerdraw = Controls_DrawKeyBinding;
1381 	s_controls.railgun.generic.id        = ID_WEAPON7;
1382 
1383 	s_controls.plasma.generic.type	    = MTYPE_ACTION;
1384 	s_controls.plasma.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1385 	s_controls.plasma.generic.callback  = Controls_ActionEvent;
1386 	s_controls.plasma.generic.ownerdraw = Controls_DrawKeyBinding;
1387 	s_controls.plasma.generic.id        = ID_WEAPON8;
1388 
1389 	s_controls.bfg.generic.type	     = MTYPE_ACTION;
1390 	s_controls.bfg.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1391 	s_controls.bfg.generic.callback  = Controls_ActionEvent;
1392 	s_controls.bfg.generic.ownerdraw = Controls_DrawKeyBinding;
1393 	s_controls.bfg.generic.id        = ID_WEAPON9;
1394 
1395 	s_controls.attack.generic.type	    = MTYPE_ACTION;
1396 	s_controls.attack.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1397 	s_controls.attack.generic.callback  = Controls_ActionEvent;
1398 	s_controls.attack.generic.ownerdraw = Controls_DrawKeyBinding;
1399 	s_controls.attack.generic.id        = ID_ATTACK;
1400 
1401 	s_controls.prevweapon.generic.type	    = MTYPE_ACTION;
1402 	s_controls.prevweapon.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1403 	s_controls.prevweapon.generic.callback  = Controls_ActionEvent;
1404 	s_controls.prevweapon.generic.ownerdraw = Controls_DrawKeyBinding;
1405 	s_controls.prevweapon.generic.id        = ID_WEAPPREV;
1406 
1407 	s_controls.nextweapon.generic.type	    = MTYPE_ACTION;
1408 	s_controls.nextweapon.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1409 	s_controls.nextweapon.generic.callback  = Controls_ActionEvent;
1410 	s_controls.nextweapon.generic.ownerdraw = Controls_DrawKeyBinding;
1411 	s_controls.nextweapon.generic.id        = ID_WEAPNEXT;
1412 
1413 	s_controls.lookup.generic.type	    = MTYPE_ACTION;
1414 	s_controls.lookup.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1415 	s_controls.lookup.generic.callback  = Controls_ActionEvent;
1416 	s_controls.lookup.generic.ownerdraw = Controls_DrawKeyBinding;
1417 	s_controls.lookup.generic.id        = ID_LOOKUP;
1418 
1419 	s_controls.lookdown.generic.type	  = MTYPE_ACTION;
1420 	s_controls.lookdown.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1421 	s_controls.lookdown.generic.callback  = Controls_ActionEvent;
1422 	s_controls.lookdown.generic.ownerdraw = Controls_DrawKeyBinding;
1423 	s_controls.lookdown.generic.id        = ID_LOOKDOWN;
1424 
1425 	s_controls.mouselook.generic.type	   = MTYPE_ACTION;
1426 	s_controls.mouselook.generic.flags     = QMF_LEFT_JUSTIFY|QMF_HIGHLIGHT_IF_FOCUS|QMF_GRAYED|QMF_HIDDEN;
1427 	s_controls.mouselook.generic.callback  = Controls_ActionEvent;
1428 	s_controls.mouselook.generic.ownerdraw = Controls_DrawKeyBinding;
1429 	s_controls.mouselook.generic.id        = ID_MOUSELOOK;
1430 
1431 	s_controls.freelook.generic.type		= MTYPE_RADIOBUTTON;
1432 	s_controls.freelook.generic.flags		= QMF_SMALLFONT;
1433 	s_controls.freelook.generic.x			= SCREEN_WIDTH/2;
1434 	s_controls.freelook.generic.name		= "free look";
1435 	s_controls.freelook.generic.id			= ID_FREELOOK;
1436 	s_controls.freelook.generic.callback	= Controls_MenuEvent;
1437 	s_controls.freelook.generic.statusbar	= Controls_StatusBar;
1438 
1439 	s_controls.centerview.generic.type	    = MTYPE_ACTION;
1440 	s_controls.centerview.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1441 	s_controls.centerview.generic.callback  = Controls_ActionEvent;
1442 	s_controls.centerview.generic.ownerdraw = Controls_DrawKeyBinding;
1443 	s_controls.centerview.generic.id        = ID_CENTERVIEW;
1444 
1445 	s_controls.zoomview.generic.type	  = MTYPE_ACTION;
1446 	s_controls.zoomview.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1447 	s_controls.zoomview.generic.callback  = Controls_ActionEvent;
1448 	s_controls.zoomview.generic.ownerdraw = Controls_DrawKeyBinding;
1449 	s_controls.zoomview.generic.id        = ID_ZOOMVIEW;
1450 
1451 	s_controls.useitem.generic.type	     = MTYPE_ACTION;
1452 	s_controls.useitem.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1453 	s_controls.useitem.generic.callback  = Controls_ActionEvent;
1454 	s_controls.useitem.generic.ownerdraw = Controls_DrawKeyBinding;
1455 	s_controls.useitem.generic.id        = ID_USEITEM;
1456 
1457 	s_controls.showscores.generic.type	    = MTYPE_ACTION;
1458 	s_controls.showscores.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1459 	s_controls.showscores.generic.callback  = Controls_ActionEvent;
1460 	s_controls.showscores.generic.ownerdraw = Controls_DrawKeyBinding;
1461 	s_controls.showscores.generic.id        = ID_SHOWSCORES;
1462 
1463 	s_controls.invertmouse.generic.type      = MTYPE_RADIOBUTTON;
1464 	s_controls.invertmouse.generic.flags	 = QMF_SMALLFONT;
1465 	s_controls.invertmouse.generic.x	     = SCREEN_WIDTH/2;
1466 	s_controls.invertmouse.generic.name	     = "invert mouse";
1467 	s_controls.invertmouse.generic.id        = ID_INVERTMOUSE;
1468 	s_controls.invertmouse.generic.callback  = Controls_MenuEvent;
1469 	s_controls.invertmouse.generic.statusbar = Controls_StatusBar;
1470 
1471 	s_controls.smoothmouse.generic.type      = MTYPE_RADIOBUTTON;
1472 	s_controls.smoothmouse.generic.flags	 = QMF_SMALLFONT;
1473 	s_controls.smoothmouse.generic.x	     = SCREEN_WIDTH/2;
1474 	s_controls.smoothmouse.generic.name	     = "smooth mouse";
1475 	s_controls.smoothmouse.generic.id        = ID_SMOOTHMOUSE;
1476 	s_controls.smoothmouse.generic.callback  = Controls_MenuEvent;
1477 	s_controls.smoothmouse.generic.statusbar = Controls_StatusBar;
1478 
1479 	s_controls.alwaysrun.generic.type      = MTYPE_RADIOBUTTON;
1480 	s_controls.alwaysrun.generic.flags	   = QMF_SMALLFONT;
1481 	s_controls.alwaysrun.generic.x	       = SCREEN_WIDTH/2;
1482 	s_controls.alwaysrun.generic.name	   = "always run";
1483 	s_controls.alwaysrun.generic.id        = ID_ALWAYSRUN;
1484 	s_controls.alwaysrun.generic.callback  = Controls_MenuEvent;
1485 	s_controls.alwaysrun.generic.statusbar = Controls_StatusBar;
1486 
1487 	s_controls.autoswitch.generic.type      = MTYPE_RADIOBUTTON;
1488 	s_controls.autoswitch.generic.flags	    = QMF_SMALLFONT;
1489 	s_controls.autoswitch.generic.x	        = SCREEN_WIDTH/2;
1490 	s_controls.autoswitch.generic.name	    = "autoswitch weapons";
1491 	s_controls.autoswitch.generic.id        = ID_AUTOSWITCH;
1492 	s_controls.autoswitch.generic.callback  = Controls_MenuEvent;
1493 	s_controls.autoswitch.generic.statusbar = Controls_StatusBar;
1494 
1495 	s_controls.sensitivity.generic.type	     = MTYPE_SLIDER;
1496 	s_controls.sensitivity.generic.x		 = SCREEN_WIDTH/2;
1497 	s_controls.sensitivity.generic.flags	 = QMF_SMALLFONT;
1498 	s_controls.sensitivity.generic.name	     = "mouse speed";
1499 	s_controls.sensitivity.generic.id 	     = ID_MOUSESPEED;
1500 	s_controls.sensitivity.generic.callback  = Controls_MenuEvent;
1501 	s_controls.sensitivity.minvalue		     = 2;
1502 	s_controls.sensitivity.maxvalue		     = 30;
1503 	s_controls.sensitivity.generic.statusbar = Controls_StatusBar;
1504 
1505 	s_controls.gesture.generic.type	     = MTYPE_ACTION;
1506 	s_controls.gesture.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1507 	s_controls.gesture.generic.callback  = Controls_ActionEvent;
1508 	s_controls.gesture.generic.ownerdraw = Controls_DrawKeyBinding;
1509 	s_controls.gesture.generic.id        = ID_GESTURE;
1510 
1511 	s_controls.chat.generic.type	  = MTYPE_ACTION;
1512 	s_controls.chat.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1513 	s_controls.chat.generic.callback  = Controls_ActionEvent;
1514 	s_controls.chat.generic.ownerdraw = Controls_DrawKeyBinding;
1515 	s_controls.chat.generic.id        = ID_CHAT;
1516 
1517 	s_controls.chat2.generic.type	   = MTYPE_ACTION;
1518 	s_controls.chat2.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1519 	s_controls.chat2.generic.callback  = Controls_ActionEvent;
1520 	s_controls.chat2.generic.ownerdraw = Controls_DrawKeyBinding;
1521 	s_controls.chat2.generic.id        = ID_CHAT2;
1522 
1523 	s_controls.chat3.generic.type	   = MTYPE_ACTION;
1524 	s_controls.chat3.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1525 	s_controls.chat3.generic.callback  = Controls_ActionEvent;
1526 	s_controls.chat3.generic.ownerdraw = Controls_DrawKeyBinding;
1527 	s_controls.chat3.generic.id        = ID_CHAT3;
1528 
1529 	s_controls.chat4.generic.type	   = MTYPE_ACTION;
1530 	s_controls.chat4.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
1531 	s_controls.chat4.generic.callback  = Controls_ActionEvent;
1532 	s_controls.chat4.generic.ownerdraw = Controls_DrawKeyBinding;
1533 	s_controls.chat4.generic.id        = ID_CHAT4;
1534 
1535 	s_controls.joyenable.generic.type      = MTYPE_RADIOBUTTON;
1536 	s_controls.joyenable.generic.flags	   = QMF_SMALLFONT;
1537 	s_controls.joyenable.generic.x	       = SCREEN_WIDTH/2;
1538 	s_controls.joyenable.generic.name	   = "joystick";
1539 	s_controls.joyenable.generic.id        = ID_JOYENABLE;
1540 	s_controls.joyenable.generic.callback  = Controls_MenuEvent;
1541 	s_controls.joyenable.generic.statusbar = Controls_StatusBar;
1542 
1543 	s_controls.joythreshold.generic.type	  = MTYPE_SLIDER;
1544 	s_controls.joythreshold.generic.x		  = SCREEN_WIDTH/2;
1545 	s_controls.joythreshold.generic.flags	  = QMF_SMALLFONT;
1546 	s_controls.joythreshold.generic.name	  = "joystick threshold";
1547 	s_controls.joythreshold.generic.id 	      = ID_JOYTHRESHOLD;
1548 	s_controls.joythreshold.generic.callback  = Controls_MenuEvent;
1549 	s_controls.joythreshold.minvalue		  = 0.05f;
1550 	s_controls.joythreshold.maxvalue		  = 0.75f;
1551 	s_controls.joythreshold.generic.statusbar = Controls_StatusBar;
1552 
1553 	s_controls.name.generic.type	= MTYPE_PTEXT;
1554 	s_controls.name.generic.flags	= QMF_CENTER_JUSTIFY|QMF_INACTIVE;
1555 	s_controls.name.generic.x		= 320;
1556 	s_controls.name.generic.y		= 440;
1557 	s_controls.name.string			= playername;
1558 	s_controls.name.style			= UI_CENTER;
1559 	s_controls.name.color			= text_color_normal;
1560 
1561 	Menu_AddItem( &s_controls.menu, &s_controls.banner );
1562 	Menu_AddItem( &s_controls.menu, &s_controls.framel );
1563 	Menu_AddItem( &s_controls.menu, &s_controls.framer );
1564 	Menu_AddItem( &s_controls.menu, &s_controls.player );
1565 	Menu_AddItem( &s_controls.menu, &s_controls.name );
1566 
1567 	Menu_AddItem( &s_controls.menu, &s_controls.looking );
1568 	Menu_AddItem( &s_controls.menu, &s_controls.movement );
1569 	Menu_AddItem( &s_controls.menu, &s_controls.weapons );
1570 	Menu_AddItem( &s_controls.menu, &s_controls.misc );
1571 
1572 	Menu_AddItem( &s_controls.menu, &s_controls.sensitivity );
1573 	Menu_AddItem( &s_controls.menu, &s_controls.smoothmouse );
1574 	Menu_AddItem( &s_controls.menu, &s_controls.invertmouse );
1575 	Menu_AddItem( &s_controls.menu, &s_controls.lookup );
1576 	Menu_AddItem( &s_controls.menu, &s_controls.lookdown );
1577 	Menu_AddItem( &s_controls.menu, &s_controls.mouselook );
1578 	Menu_AddItem( &s_controls.menu, &s_controls.freelook );
1579 	Menu_AddItem( &s_controls.menu, &s_controls.centerview );
1580 	Menu_AddItem( &s_controls.menu, &s_controls.zoomview );
1581 	Menu_AddItem( &s_controls.menu, &s_controls.joyenable );
1582 	Menu_AddItem( &s_controls.menu, &s_controls.joythreshold );
1583 
1584 	Menu_AddItem( &s_controls.menu, &s_controls.alwaysrun );
1585 	Menu_AddItem( &s_controls.menu, &s_controls.run );
1586 	Menu_AddItem( &s_controls.menu, &s_controls.walkforward );
1587 	Menu_AddItem( &s_controls.menu, &s_controls.backpedal );
1588 	Menu_AddItem( &s_controls.menu, &s_controls.stepleft );
1589 	Menu_AddItem( &s_controls.menu, &s_controls.stepright );
1590 	Menu_AddItem( &s_controls.menu, &s_controls.moveup );
1591 	Menu_AddItem( &s_controls.menu, &s_controls.movedown );
1592 	Menu_AddItem( &s_controls.menu, &s_controls.turnleft );
1593 	Menu_AddItem( &s_controls.menu, &s_controls.turnright );
1594 	Menu_AddItem( &s_controls.menu, &s_controls.sidestep );
1595 
1596 	Menu_AddItem( &s_controls.menu, &s_controls.attack );
1597 	Menu_AddItem( &s_controls.menu, &s_controls.nextweapon );
1598 	Menu_AddItem( &s_controls.menu, &s_controls.prevweapon );
1599 	Menu_AddItem( &s_controls.menu, &s_controls.autoswitch );
1600 	Menu_AddItem( &s_controls.menu, &s_controls.chainsaw );
1601 	Menu_AddItem( &s_controls.menu, &s_controls.machinegun );
1602 	Menu_AddItem( &s_controls.menu, &s_controls.shotgun );
1603 	Menu_AddItem( &s_controls.menu, &s_controls.grenadelauncher );
1604 	Menu_AddItem( &s_controls.menu, &s_controls.rocketlauncher );
1605 	Menu_AddItem( &s_controls.menu, &s_controls.lightning );
1606 	Menu_AddItem( &s_controls.menu, &s_controls.railgun );
1607 	Menu_AddItem( &s_controls.menu, &s_controls.plasma );
1608 	Menu_AddItem( &s_controls.menu, &s_controls.bfg );
1609 
1610 	Menu_AddItem( &s_controls.menu, &s_controls.showscores );
1611 	Menu_AddItem( &s_controls.menu, &s_controls.useitem );
1612 	Menu_AddItem( &s_controls.menu, &s_controls.gesture );
1613 	Menu_AddItem( &s_controls.menu, &s_controls.chat );
1614 	Menu_AddItem( &s_controls.menu, &s_controls.chat2 );
1615 	Menu_AddItem( &s_controls.menu, &s_controls.chat3 );
1616 	Menu_AddItem( &s_controls.menu, &s_controls.chat4 );
1617 
1618 	Menu_AddItem( &s_controls.menu, &s_controls.back );
1619 
1620 	trap_Cvar_VariableStringBuffer( "name", s_controls.name.string, 16 );
1621 	Q_CleanStr( s_controls.name.string );
1622 
1623 	// initialize the configurable cvars
1624 	Controls_InitCvars();
1625 
1626 	// initialize the current config
1627 	Controls_GetConfig();
1628 
1629 	// intialize the model
1630 	Controls_InitModel();
1631 
1632 	// intialize the weapons
1633 	Controls_InitWeapons ();
1634 
1635 	// initial default section
1636 	s_controls.section = C_LOOKING;
1637 
1638 	// update the ui
1639 	Controls_Update();
1640 }
1641 
1642 
1643 /*
1644 =================
1645 Controls_Cache
1646 =================
1647 */
Controls_Cache(void)1648 void Controls_Cache( void ) {
1649 	trap_R_RegisterShaderNoMip( ART_BACK0 );
1650 	trap_R_RegisterShaderNoMip( ART_BACK1 );
1651 	trap_R_RegisterShaderNoMip( ART_FRAMEL );
1652 	trap_R_RegisterShaderNoMip( ART_FRAMER );
1653 }
1654 
1655 
1656 /*
1657 =================
1658 UI_ControlsMenu
1659 =================
1660 */
UI_ControlsMenu(void)1661 void UI_ControlsMenu( void ) {
1662 	Controls_MenuInit();
1663 	UI_PushMenu( &s_controls.menu );
1664 }
1665