ui_playersettings.c (15014B)
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 #include "ui_local.h" 24 25 #define ART_FRAMEL "menu/art/frame2_l" 26 #define ART_FRAMER "menu/art/frame1_r" 27 #define ART_MODEL0 "menu/art/model_0" 28 #define ART_MODEL1 "menu/art/model_1" 29 #define ART_BACK0 "menu/art/back_0" 30 #define ART_BACK1 "menu/art/back_1" 31 #define ART_FX_BASE "menu/art/fx_base" 32 #define ART_FX_BLUE "menu/art/fx_blue" 33 #define ART_FX_CYAN "menu/art/fx_cyan" 34 #define ART_FX_GREEN "menu/art/fx_grn" 35 #define ART_FX_RED "menu/art/fx_red" 36 #define ART_FX_TEAL "menu/art/fx_teal" 37 #define ART_FX_WHITE "menu/art/fx_white" 38 #define ART_FX_YELLOW "menu/art/fx_yel" 39 40 #define ID_NAME 10 41 #define ID_HANDICAP 11 42 #define ID_EFFECTS 12 43 #define ID_BACK 13 44 #define ID_MODEL 14 45 46 #define MAX_NAMELENGTH 20 47 48 49 typedef struct { 50 menuframework_s menu; 51 52 menutext_s banner; 53 menubitmap_s framel; 54 menubitmap_s framer; 55 menubitmap_s player; 56 57 menufield_s name; 58 menulist_s handicap; 59 menulist_s effects; 60 61 menubitmap_s back; 62 menubitmap_s model; 63 menubitmap_s item_null; 64 65 qhandle_t fxBasePic; 66 qhandle_t fxPic[7]; 67 playerInfo_t playerinfo; 68 int current_fx; 69 char playerModel[MAX_QPATH]; 70 } playersettings_t; 71 72 static playersettings_t s_playersettings; 73 74 static int gamecodetoui[] = {4,2,3,0,5,1,6}; 75 static int uitogamecode[] = {4,6,2,3,1,5,7}; 76 77 static const char *handicap_items[] = { 78 "None", 79 "95", 80 "90", 81 "85", 82 "80", 83 "75", 84 "70", 85 "65", 86 "60", 87 "55", 88 "50", 89 "45", 90 "40", 91 "35", 92 "30", 93 "25", 94 "20", 95 "15", 96 "10", 97 "5", 98 0 99 }; 100 101 102 /* 103 ================= 104 PlayerSettings_DrawName 105 ================= 106 */ 107 static void PlayerSettings_DrawName( void *self ) { 108 menufield_s *f; 109 qboolean focus; 110 int style; 111 char *txt; 112 char c; 113 float *color; 114 int n; 115 int basex, x, y; 116 char name[32]; 117 118 f = (menufield_s*)self; 119 basex = f->generic.x; 120 y = f->generic.y; 121 focus = (f->generic.parent->cursor == f->generic.menuPosition); 122 123 style = UI_LEFT|UI_SMALLFONT; 124 color = text_color_normal; 125 if( focus ) { 126 style |= UI_PULSE; 127 color = text_color_highlight; 128 } 129 130 UI_DrawProportionalString( basex, y, "Name", style, color ); 131 132 // draw the actual name 133 basex += 64; 134 y += PROP_HEIGHT; 135 txt = f->field.buffer; 136 color = g_color_table[ColorIndex(COLOR_WHITE)]; 137 x = basex; 138 while ( (c = *txt) != 0 ) { 139 if ( !focus && Q_IsColorString( txt ) ) { 140 n = ColorIndex( *(txt+1) ); 141 if( n == 0 ) { 142 n = 7; 143 } 144 color = g_color_table[n]; 145 txt += 2; 146 continue; 147 } 148 UI_DrawChar( x, y, c, style, color ); 149 txt++; 150 x += SMALLCHAR_WIDTH; 151 } 152 153 // draw cursor if we have focus 154 if( focus ) { 155 if ( trap_Key_GetOverstrikeMode() ) { 156 c = 11; 157 } else { 158 c = 10; 159 } 160 161 style &= ~UI_PULSE; 162 style |= UI_BLINK; 163 164 UI_DrawChar( basex + f->field.cursor * SMALLCHAR_WIDTH, y, c, style, color_white ); 165 } 166 167 // draw at bottom also using proportional font 168 Q_strncpyz( name, f->field.buffer, sizeof(name) ); 169 Q_CleanStr( name ); 170 UI_DrawProportionalString( 320, 440, name, UI_CENTER|UI_BIGFONT, text_color_normal ); 171 } 172 173 174 /* 175 ================= 176 PlayerSettings_DrawHandicap 177 ================= 178 */ 179 static void PlayerSettings_DrawHandicap( void *self ) { 180 menulist_s *item; 181 qboolean focus; 182 int style; 183 float *color; 184 185 item = (menulist_s *)self; 186 focus = (item->generic.parent->cursor == item->generic.menuPosition); 187 188 style = UI_LEFT|UI_SMALLFONT; 189 color = text_color_normal; 190 if( focus ) { 191 style |= UI_PULSE; 192 color = text_color_highlight; 193 } 194 195 UI_DrawProportionalString( item->generic.x, item->generic.y, "Handicap", style, color ); 196 UI_DrawProportionalString( item->generic.x + 64, item->generic.y + PROP_HEIGHT, handicap_items[item->curvalue], style, color ); 197 } 198 199 200 /* 201 ================= 202 PlayerSettings_DrawEffects 203 ================= 204 */ 205 static void PlayerSettings_DrawEffects( void *self ) { 206 menulist_s *item; 207 qboolean focus; 208 int style; 209 float *color; 210 211 item = (menulist_s *)self; 212 focus = (item->generic.parent->cursor == item->generic.menuPosition); 213 214 style = UI_LEFT|UI_SMALLFONT; 215 color = text_color_normal; 216 if( focus ) { 217 style |= UI_PULSE; 218 color = text_color_highlight; 219 } 220 221 UI_DrawProportionalString( item->generic.x, item->generic.y, "Effects", style, color ); 222 223 UI_DrawHandlePic( item->generic.x + 64, item->generic.y + PROP_HEIGHT + 8, 128, 8, s_playersettings.fxBasePic ); 224 UI_DrawHandlePic( item->generic.x + 64 + item->curvalue * 16 + 8, item->generic.y + PROP_HEIGHT + 6, 16, 12, s_playersettings.fxPic[item->curvalue] ); 225 } 226 227 228 /* 229 ================= 230 PlayerSettings_DrawPlayer 231 ================= 232 */ 233 static void PlayerSettings_DrawPlayer( void *self ) { 234 menubitmap_s *b; 235 vec3_t viewangles; 236 char buf[MAX_QPATH]; 237 238 trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) ); 239 if ( strcmp( buf, s_playersettings.playerModel ) != 0 ) { 240 UI_PlayerInfo_SetModel( &s_playersettings.playerinfo, buf ); 241 strcpy( s_playersettings.playerModel, buf ); 242 243 viewangles[YAW] = 180 - 30; 244 viewangles[PITCH] = 0; 245 viewangles[ROLL] = 0; 246 UI_PlayerInfo_SetInfo( &s_playersettings.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); 247 } 248 249 b = (menubitmap_s*) self; 250 UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_playersettings.playerinfo, uis.realtime/2 ); 251 } 252 253 254 /* 255 ================= 256 PlayerSettings_SaveChanges 257 ================= 258 */ 259 static void PlayerSettings_SaveChanges( void ) { 260 // name 261 trap_Cvar_Set( "name", s_playersettings.name.field.buffer ); 262 263 // handicap 264 trap_Cvar_SetValue( "handicap", 100 - s_playersettings.handicap.curvalue * 5 ); 265 266 // effects color 267 trap_Cvar_SetValue( "color1", uitogamecode[s_playersettings.effects.curvalue] ); 268 } 269 270 271 /* 272 ================= 273 PlayerSettings_MenuKey 274 ================= 275 */ 276 static sfxHandle_t PlayerSettings_MenuKey( int key ) { 277 if( key == K_MOUSE2 || key == K_ESCAPE ) { 278 PlayerSettings_SaveChanges(); 279 } 280 return Menu_DefaultKey( &s_playersettings.menu, key ); 281 } 282 283 284 /* 285 ================= 286 PlayerSettings_SetMenuItems 287 ================= 288 */ 289 static void PlayerSettings_SetMenuItems( void ) { 290 vec3_t viewangles; 291 int c; 292 int h; 293 294 // name 295 Q_strncpyz( s_playersettings.name.field.buffer, UI_Cvar_VariableString("name"), sizeof(s_playersettings.name.field.buffer) ); 296 297 // effects color 298 c = trap_Cvar_VariableValue( "color1" ) - 1; 299 if( c < 0 || c > 6 ) { 300 c = 6; 301 } 302 s_playersettings.effects.curvalue = gamecodetoui[c]; 303 304 // model/skin 305 memset( &s_playersettings.playerinfo, 0, sizeof(playerInfo_t) ); 306 307 viewangles[YAW] = 180 - 30; 308 viewangles[PITCH] = 0; 309 viewangles[ROLL] = 0; 310 311 UI_PlayerInfo_SetModel( &s_playersettings.playerinfo, UI_Cvar_VariableString( "model" ) ); 312 UI_PlayerInfo_SetInfo( &s_playersettings.playerinfo, LEGS_IDLE, TORSO_STAND, viewangles, vec3_origin, WP_MACHINEGUN, qfalse ); 313 314 // handicap 315 h = Com_Clamp( 5, 100, trap_Cvar_VariableValue("handicap") ); 316 s_playersettings.handicap.curvalue = 20 - h / 5; 317 } 318 319 320 /* 321 ================= 322 PlayerSettings_MenuEvent 323 ================= 324 */ 325 static void PlayerSettings_MenuEvent( void* ptr, int event ) { 326 if( event != QM_ACTIVATED ) { 327 return; 328 } 329 330 switch( ((menucommon_s*)ptr)->id ) { 331 case ID_HANDICAP: 332 trap_Cvar_Set( "handicap", va( "%i", 100 - 25 * s_playersettings.handicap.curvalue ) ); 333 break; 334 335 case ID_MODEL: 336 PlayerSettings_SaveChanges(); 337 UI_PlayerModelMenu(); 338 break; 339 340 case ID_BACK: 341 PlayerSettings_SaveChanges(); 342 UI_PopMenu(); 343 break; 344 } 345 } 346 347 348 /* 349 ================= 350 PlayerSettings_MenuInit 351 ================= 352 */ 353 static void PlayerSettings_MenuInit( void ) { 354 int y; 355 356 memset(&s_playersettings,0,sizeof(playersettings_t)); 357 358 PlayerSettings_Cache(); 359 360 s_playersettings.menu.key = PlayerSettings_MenuKey; 361 s_playersettings.menu.wrapAround = qtrue; 362 s_playersettings.menu.fullscreen = qtrue; 363 364 s_playersettings.banner.generic.type = MTYPE_BTEXT; 365 s_playersettings.banner.generic.x = 320; 366 s_playersettings.banner.generic.y = 16; 367 s_playersettings.banner.string = "PLAYER SETTINGS"; 368 s_playersettings.banner.color = color_white; 369 s_playersettings.banner.style = UI_CENTER; 370 371 s_playersettings.framel.generic.type = MTYPE_BITMAP; 372 s_playersettings.framel.generic.name = ART_FRAMEL; 373 s_playersettings.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; 374 s_playersettings.framel.generic.x = 0; 375 s_playersettings.framel.generic.y = 78; 376 s_playersettings.framel.width = 256; 377 s_playersettings.framel.height = 329; 378 379 s_playersettings.framer.generic.type = MTYPE_BITMAP; 380 s_playersettings.framer.generic.name = ART_FRAMER; 381 s_playersettings.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE; 382 s_playersettings.framer.generic.x = 376; 383 s_playersettings.framer.generic.y = 76; 384 s_playersettings.framer.width = 256; 385 s_playersettings.framer.height = 334; 386 387 y = 144; 388 s_playersettings.name.generic.type = MTYPE_FIELD; 389 s_playersettings.name.generic.flags = QMF_NODEFAULTINIT; 390 s_playersettings.name.generic.ownerdraw = PlayerSettings_DrawName; 391 s_playersettings.name.field.widthInChars = MAX_NAMELENGTH; 392 s_playersettings.name.field.maxchars = MAX_NAMELENGTH; 393 s_playersettings.name.generic.x = 192; 394 s_playersettings.name.generic.y = y; 395 s_playersettings.name.generic.left = 192 - 8; 396 s_playersettings.name.generic.top = y - 8; 397 s_playersettings.name.generic.right = 192 + 200; 398 s_playersettings.name.generic.bottom = y + 2 * PROP_HEIGHT; 399 400 y += 3 * PROP_HEIGHT; 401 s_playersettings.handicap.generic.type = MTYPE_SPINCONTROL; 402 s_playersettings.handicap.generic.flags = QMF_NODEFAULTINIT; 403 s_playersettings.handicap.generic.id = ID_HANDICAP; 404 s_playersettings.handicap.generic.ownerdraw = PlayerSettings_DrawHandicap; 405 s_playersettings.handicap.generic.x = 192; 406 s_playersettings.handicap.generic.y = y; 407 s_playersettings.handicap.generic.left = 192 - 8; 408 s_playersettings.handicap.generic.top = y - 8; 409 s_playersettings.handicap.generic.right = 192 + 200; 410 s_playersettings.handicap.generic.bottom = y + 2 * PROP_HEIGHT; 411 s_playersettings.handicap.numitems = 20; 412 413 y += 3 * PROP_HEIGHT; 414 s_playersettings.effects.generic.type = MTYPE_SPINCONTROL; 415 s_playersettings.effects.generic.flags = QMF_NODEFAULTINIT; 416 s_playersettings.effects.generic.id = ID_EFFECTS; 417 s_playersettings.effects.generic.ownerdraw = PlayerSettings_DrawEffects; 418 s_playersettings.effects.generic.x = 192; 419 s_playersettings.effects.generic.y = y; 420 s_playersettings.effects.generic.left = 192 - 8; 421 s_playersettings.effects.generic.top = y - 8; 422 s_playersettings.effects.generic.right = 192 + 200; 423 s_playersettings.effects.generic.bottom = y + 2* PROP_HEIGHT; 424 s_playersettings.effects.numitems = 7; 425 426 s_playersettings.model.generic.type = MTYPE_BITMAP; 427 s_playersettings.model.generic.name = ART_MODEL0; 428 s_playersettings.model.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS; 429 s_playersettings.model.generic.id = ID_MODEL; 430 s_playersettings.model.generic.callback = PlayerSettings_MenuEvent; 431 s_playersettings.model.generic.x = 640; 432 s_playersettings.model.generic.y = 480-64; 433 s_playersettings.model.width = 128; 434 s_playersettings.model.height = 64; 435 s_playersettings.model.focuspic = ART_MODEL1; 436 437 s_playersettings.player.generic.type = MTYPE_BITMAP; 438 s_playersettings.player.generic.flags = QMF_INACTIVE; 439 s_playersettings.player.generic.ownerdraw = PlayerSettings_DrawPlayer; 440 s_playersettings.player.generic.x = 400; 441 s_playersettings.player.generic.y = -40; 442 s_playersettings.player.width = 32*10; 443 s_playersettings.player.height = 56*10; 444 445 s_playersettings.back.generic.type = MTYPE_BITMAP; 446 s_playersettings.back.generic.name = ART_BACK0; 447 s_playersettings.back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS; 448 s_playersettings.back.generic.id = ID_BACK; 449 s_playersettings.back.generic.callback = PlayerSettings_MenuEvent; 450 s_playersettings.back.generic.x = 0; 451 s_playersettings.back.generic.y = 480-64; 452 s_playersettings.back.width = 128; 453 s_playersettings.back.height = 64; 454 s_playersettings.back.focuspic = ART_BACK1; 455 456 s_playersettings.item_null.generic.type = MTYPE_BITMAP; 457 s_playersettings.item_null.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY|QMF_SILENT; 458 s_playersettings.item_null.generic.x = 0; 459 s_playersettings.item_null.generic.y = 0; 460 s_playersettings.item_null.width = 640; 461 s_playersettings.item_null.height = 480; 462 463 Menu_AddItem( &s_playersettings.menu, &s_playersettings.banner ); 464 Menu_AddItem( &s_playersettings.menu, &s_playersettings.framel ); 465 Menu_AddItem( &s_playersettings.menu, &s_playersettings.framer ); 466 467 Menu_AddItem( &s_playersettings.menu, &s_playersettings.name ); 468 Menu_AddItem( &s_playersettings.menu, &s_playersettings.handicap ); 469 Menu_AddItem( &s_playersettings.menu, &s_playersettings.effects ); 470 Menu_AddItem( &s_playersettings.menu, &s_playersettings.model ); 471 Menu_AddItem( &s_playersettings.menu, &s_playersettings.back ); 472 473 Menu_AddItem( &s_playersettings.menu, &s_playersettings.player ); 474 475 Menu_AddItem( &s_playersettings.menu, &s_playersettings.item_null ); 476 477 PlayerSettings_SetMenuItems(); 478 } 479 480 481 /* 482 ================= 483 PlayerSettings_Cache 484 ================= 485 */ 486 void PlayerSettings_Cache( void ) { 487 trap_R_RegisterShaderNoMip( ART_FRAMEL ); 488 trap_R_RegisterShaderNoMip( ART_FRAMER ); 489 trap_R_RegisterShaderNoMip( ART_MODEL0 ); 490 trap_R_RegisterShaderNoMip( ART_MODEL1 ); 491 trap_R_RegisterShaderNoMip( ART_BACK0 ); 492 trap_R_RegisterShaderNoMip( ART_BACK1 ); 493 494 s_playersettings.fxBasePic = trap_R_RegisterShaderNoMip( ART_FX_BASE ); 495 s_playersettings.fxPic[0] = trap_R_RegisterShaderNoMip( ART_FX_RED ); 496 s_playersettings.fxPic[1] = trap_R_RegisterShaderNoMip( ART_FX_YELLOW ); 497 s_playersettings.fxPic[2] = trap_R_RegisterShaderNoMip( ART_FX_GREEN ); 498 s_playersettings.fxPic[3] = trap_R_RegisterShaderNoMip( ART_FX_TEAL ); 499 s_playersettings.fxPic[4] = trap_R_RegisterShaderNoMip( ART_FX_BLUE ); 500 s_playersettings.fxPic[5] = trap_R_RegisterShaderNoMip( ART_FX_CYAN ); 501 s_playersettings.fxPic[6] = trap_R_RegisterShaderNoMip( ART_FX_WHITE ); 502 } 503 504 505 /* 506 ================= 507 UI_PlayerSettingsMenu 508 ================= 509 */ 510 void UI_PlayerSettingsMenu( void ) { 511 PlayerSettings_MenuInit(); 512 UI_PushMenu( &s_playersettings.menu ); 513 }