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 // ui_rankings.c
25 //
26 
27 #include "ui_local.h"
28 
29 
30 #define RANKINGS_FRAME	"menu/art/cut_frame"
31 
32 #define ID_LOGIN		100
33 #define ID_LOGOUT		101
34 #define ID_CREATE		102
35 #define ID_SPECTATE		103
36 #define ID_SETUP		104
37 #define ID_LEAVE		105
38 
39 
40 typedef struct
41 {
42 	menuframework_s	menu;
43 	menubitmap_s	frame;
44 	menutext_s		login;
45 	menutext_s		logout;
46 	menutext_s		create;
47 	menutext_s		spectate;
48 	menutext_s		setup;
49 	menutext_s		leave;
50 } rankings_t;
51 
52 static rankings_t	s_rankings;
53 
54 static menuframework_s	s_rankings_menu;
55 static menuaction_s		s_rankings_login;
56 static menuaction_s		s_rankings_logout;
57 static menuaction_s		s_rankings_create;
58 static menuaction_s		s_rankings_spectate;
59 static menuaction_s		s_rankings_setup;
60 static menuaction_s		s_rankings_leave;
61 
62 
63 /*
64 ===============
65 Rankings_DrawText
66 ===============
67 */
Rankings_DrawText(void * self)68 void Rankings_DrawText( void* self )
69 {
70 	menufield_s		*f;
71 	qboolean		focus;
72 	int				style;
73 	char			*txt;
74 	char			c;
75 	float			*color;
76 	int				basex, x, y;
77 
78 	f = (menufield_s*)self;
79 	basex = f->generic.x;
80 	y = f->generic.y + 4;
81 	focus = (f->generic.parent->cursor == f->generic.menuPosition);
82 
83 	style = UI_LEFT|UI_SMALLFONT;
84 	color = text_color_normal;
85 	if( focus ) {
86 		style |= UI_PULSE;
87 		color = text_color_highlight;
88 	}
89 
90 	// draw the actual text
91 	txt = f->field.buffer;
92 	color = g_color_table[ColorIndex(COLOR_WHITE)];
93 	x = basex;
94 	while ( (c = *txt) != 0 ) {
95 		UI_DrawChar( x, y, c, style, color );
96 		txt++;
97 		x += SMALLCHAR_WIDTH;
98 	}
99 
100 	// draw cursor if we have focus
101 	if( focus ) {
102 		if ( trap_Key_GetOverstrikeMode() ) {
103 			c = 11;
104 		} else {
105 			c = 10;
106 		}
107 
108 		style &= ~UI_PULSE;
109 		style |= UI_BLINK;
110 
111 		UI_DrawChar( basex + f->field.cursor * SMALLCHAR_WIDTH, y, c, style, color_white );
112 	}
113 }
114 
115 /*
116 ===============
117 Rankings_DrawName
118 ===============
119 */
Rankings_DrawName(void * self)120 void Rankings_DrawName( void* self )
121 {
122 	menufield_s		*f;
123 	int				length;
124 	char*			p;
125 
126 	f = (menufield_s*)self;
127 
128 	// GRANK_FIXME - enforce valid characters
129 	for( p = f->field.buffer; *p != '\0'; p++ )
130 	{
131 		//if( ispunct(*p) || isspace(*p) )
132 		if( !( ( (*p) >= '0' && (*p) <= '9') || Q_isalpha(*p)) )
133 		{
134 			*p = '\0';
135 		}
136 	}
137 
138 	// strip color codes
139 	Q_CleanStr( f->field.buffer );
140 	length = strlen( f->field.buffer );
141 	if( f->field.cursor > length )
142 	{
143 		f->field.cursor = length;
144 	}
145 
146 	Rankings_DrawText( f );
147 }
148 
149 #if 0 // old version
150 /*
151 ===============
152 Rankings_DrawName
153 ===============
154 */
155 void Rankings_DrawName( void* self )
156 {
157 	menufield_s*	f;
158 	int				length;
159 
160 	f = (menufield_s*)self;
161 
162 	// strip color codes
163 	Q_CleanStr( f->field.buffer );
164 	length = strlen( f->field.buffer );
165 	if( f->field.cursor > length )
166 	{
167 		f->field.cursor = length;
168 	}
169 
170 	// show beginning of long names
171 	/*
172 	if( Menu_ItemAtCursor( f->generic.parent ) != f )
173 	{
174 		if( f->field.scroll > 0 )
175 		{
176 			f->field.cursor = 0;
177 			f->field.scroll = 0;
178 		}
179 	}
180 	*/
181 
182 	MenuField_Draw( f );
183 }
184 #endif
185 
186 /*
187 ===============
188 Rankings_DrawPassword
189 ===============
190 */
Rankings_DrawPassword(void * self)191 void Rankings_DrawPassword( void* self )
192 {
193 	menufield_s*	f;
194 	char			password[MAX_EDIT_LINE];
195 	int				length;
196 	int				i;
197 	char*			p;
198 
199 	f = (menufield_s*)self;
200 
201 	// GRANK_FIXME - enforce valid characters
202 	for( p = f->field.buffer; *p != '\0'; p++ )
203 	{
204 		//if( ispunct(*p) || isspace(*p) )
205 		if( !( ( (*p) >= '0' && (*p) <= '9') || Q_isalpha(*p)) )
206 		{
207 			*p = '\0';
208 		}
209 	}
210 
211 	length = strlen( f->field.buffer );
212 	if( f->field.cursor > length )
213 	{
214 		f->field.cursor = length;
215 	}
216 
217 	// save password
218 	Q_strncpyz( password, f->field.buffer, sizeof(password) );
219 
220 	// mask password with *
221 	for( i = 0; i < length; i++ )
222 	{
223 		f->field.buffer[i] = '*';
224 	}
225 
226 	// draw masked password
227 	Rankings_DrawText( f );
228 	//MenuField_Draw( f );
229 
230 	// restore password
231 	Q_strncpyz( f->field.buffer, password, sizeof(f->field.buffer) );
232 }
233 
234 /*
235 ===============
236 Rankings_MenuEvent
237 ===============
238 */
Rankings_MenuEvent(void * ptr,int event)239 static void Rankings_MenuEvent( void* ptr, int event ) {
240 	if( event != QM_ACTIVATED ) {
241 		return;
242 	}
243 
244 	switch( ((menucommon_s*)ptr)->id ) {
245 	case ID_LOGIN:
246 		UI_LoginMenu();
247 		break;
248 
249 	case ID_LOGOUT:
250 		// server side masqueraded player logout first
251 		trap_CL_UI_RankUserRequestLogout();
252 		UI_ForceMenuOff();
253 		break;
254 
255 	case ID_CREATE:
256 		UI_SignupMenu();
257 		break;
258 
259 	case ID_SPECTATE:
260 		trap_Cmd_ExecuteText( EXEC_APPEND, "cmd rank_spectate\n" );
261 		UI_ForceMenuOff();
262 		break;
263 
264 	case ID_SETUP:
265 		UI_SetupMenu();
266 		break;
267 
268 	case ID_LEAVE:
269 		trap_Cmd_ExecuteText( EXEC_APPEND, "disconnect\n" );
270 		UI_ForceMenuOff();
271 		break;
272 
273 	}
274 }
275 
276 
277 /*
278 ===============
279 Rankings_MenuInit
280 ===============
281 */
Rankings_MenuInit(void)282 void Rankings_MenuInit( void ) {
283 	grank_status_t	status;
284 	int				y;
285 
286 	memset( &s_rankings, 0, sizeof(s_rankings) );
287 
288 	Rankings_Cache();
289 
290 	s_rankings.menu.wrapAround = qtrue;
291 	s_rankings.menu.fullscreen = qfalse;
292 
293 	s_rankings.frame.generic.type		= MTYPE_BITMAP;
294 	s_rankings.frame.generic.flags		= QMF_INACTIVE;
295 	s_rankings.frame.generic.name		= RANKINGS_FRAME;
296 	s_rankings.frame.generic.x			= 142;
297 	s_rankings.frame.generic.y			= 118;
298 	s_rankings.frame.width				= 359;
299 	s_rankings.frame.height				= 256;
300 
301 	y = 194;
302 
303 	s_rankings.login.generic.type		= MTYPE_PTEXT;
304 	s_rankings.login.generic.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
305 	s_rankings.login.generic.id			= ID_LOGIN;
306 	s_rankings.login.generic.callback	= Rankings_MenuEvent;
307 	s_rankings.login.generic.x			= 320;
308 	s_rankings.login.generic.y			= y;
309 	s_rankings.login.string				= "LOGIN";
310 	s_rankings.login.style				= UI_CENTER|UI_SMALLFONT;
311 	s_rankings.login.color				= colorRed;
312 	y += 20;
313 
314 	s_rankings.logout.generic.type		= MTYPE_PTEXT;
315 	s_rankings.logout.generic.flags		= QMF_HIDDEN|QMF_INACTIVE|QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
316 	s_rankings.logout.generic.id		= ID_LOGOUT;
317 	s_rankings.logout.generic.callback	= Rankings_MenuEvent;
318 	s_rankings.logout.generic.x			= 320;
319 	s_rankings.logout.generic.y			= y;
320 	s_rankings.logout.string				= "LOGOUT";
321 	s_rankings.logout.style				= UI_CENTER|UI_SMALLFONT;
322 	s_rankings.logout.color				= colorRed;
323 
324 	s_rankings.create.generic.type		= MTYPE_PTEXT;
325 	s_rankings.create.generic.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
326 	s_rankings.create.generic.id		= ID_CREATE;
327 	s_rankings.create.generic.callback	= Rankings_MenuEvent;
328 	s_rankings.create.generic.x			= 320;
329 	s_rankings.create.generic.y			= y;
330 	s_rankings.create.string			= "SIGN UP";
331 	s_rankings.create.style				= UI_CENTER|UI_SMALLFONT;
332 	s_rankings.create.color				= colorRed;
333 	y += 20;
334 
335 	s_rankings.spectate.generic.type		= MTYPE_PTEXT;
336 	s_rankings.spectate.generic.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
337 	s_rankings.spectate.generic.id			= ID_SPECTATE;
338 	s_rankings.spectate.generic.callback	= Rankings_MenuEvent;
339 	s_rankings.spectate.generic.x			= 320;
340 	s_rankings.spectate.generic.y			= y;
341 	s_rankings.spectate.string				= "SPECTATE";
342 	s_rankings.spectate.style				= UI_CENTER|UI_SMALLFONT;
343 	s_rankings.spectate.color				= colorRed;
344 	y += 20;
345 
346 	s_rankings.setup.generic.type		= MTYPE_PTEXT;
347 	s_rankings.setup.generic.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
348 	s_rankings.setup.generic.id			= ID_SETUP;
349 	s_rankings.setup.generic.callback	= Rankings_MenuEvent;
350 	s_rankings.setup.generic.x			= 320;
351 	s_rankings.setup.generic.y			= y;
352 	s_rankings.setup.string				= "SETUP";
353 	s_rankings.setup.style				= UI_CENTER|UI_SMALLFONT;
354 	s_rankings.setup.color				= colorRed;
355 	y += 20;
356 
357 	s_rankings.leave.generic.type		= MTYPE_PTEXT;
358 	s_rankings.leave.generic.flags		= QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
359 	s_rankings.leave.generic.id			= ID_LEAVE;
360 	s_rankings.leave.generic.callback	= Rankings_MenuEvent;
361 	s_rankings.leave.generic.x			= 320;
362 	s_rankings.leave.generic.y			= y;
363 	s_rankings.leave.string				= "LEAVE ARENA";
364 	s_rankings.leave.style				= UI_CENTER|UI_SMALLFONT;
365 	s_rankings.leave.color				= colorRed;
366 	y += 20;
367 
368 	status = (grank_status_t)trap_Cvar_VariableValue("client_status");
369 	if( (status != QGR_STATUS_NEW) && (status != QGR_STATUS_SPECTATOR) )
370 	{
371 		s_rankings.login.generic.flags |= QMF_HIDDEN | QMF_INACTIVE;
372 		s_rankings.create.generic.flags |= QMF_HIDDEN | QMF_INACTIVE;
373 		s_rankings.spectate.generic.flags |= QMF_HIDDEN | QMF_INACTIVE;
374 
375 		s_rankings.logout.generic.flags &= ~(QMF_HIDDEN | QMF_INACTIVE);
376 	}
377 
378 	if ( (status == QGR_STATUS_VALIDATING) ||
379 		 (status == QGR_STATUS_PENDING) ||
380 		 (status == QGR_STATUS_LEAVING) )
381 	{
382 		s_rankings.login.generic.flags  |= QMF_GRAYED;
383 		s_rankings.create.generic.flags |= QMF_GRAYED;
384 		s_rankings.logout.generic.flags |= QMF_GRAYED;
385 	}
386 
387 	//GRank FIXME -- don't need setup option any more
388 	s_rankings.setup.generic.flags |= QMF_HIDDEN | QMF_INACTIVE;
389 
390 	Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.frame );
391 	Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.login );
392 	Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.logout );
393 	Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.create );
394 	Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.spectate );
395 	Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.setup );
396 	Menu_AddItem( &s_rankings.menu, (void*) &s_rankings.leave );
397 }
398 
399 
400 /*
401 ===============
402 Rankings_Cache
403 ===============
404 */
Rankings_Cache(void)405 void Rankings_Cache( void ) {
406 	trap_R_RegisterShaderNoMip( RANKINGS_FRAME );
407 }
408 
409 
410 /*
411 ===============
412 UI_RankingsMenu
413 ===============
414 */
UI_RankingsMenu(void)415 void UI_RankingsMenu( void ) {
416 	Rankings_MenuInit();
417 	UI_PushMenu ( &s_rankings.menu );
418 }
419 
420 
421