2
===========================================================================
3
Copyright (C) 1999-2005 Id Software, Inc.
5
This file is part of Quake III Arena source code.
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.
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.
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
===========================================================================
24
=============================================================================
26
SINGLE PLAYER LEVEL SELECT MENU
28
=============================================================================
34
#define ART_LEVELFRAME_FOCUS "menu/art/maps_select"
35
#define ART_LEVELFRAME_SELECTED "menu/art/maps_selected"
36
#define ART_ARROW "menu/art/narrow_0"
37
#define ART_ARROW_FOCUS "menu/art/narrow_1"
38
#define ART_MAP_UNKNOWN "menu/art/unknownmap"
39
#define ART_MAP_COMPLETE1 "menu/art/level_complete1"
40
#define ART_MAP_COMPLETE2 "menu/art/level_complete2"
41
#define ART_MAP_COMPLETE3 "menu/art/level_complete3"
42
#define ART_MAP_COMPLETE4 "menu/art/level_complete4"
43
#define ART_MAP_COMPLETE5 "menu/art/level_complete5"
44
#define ART_BACK0 "menu/art/back_0"
45
#define ART_BACK1 "menu/art/back_1"
46
#define ART_FIGHT0 "menu/art/fight_0"
47
#define ART_FIGHT1 "menu/art/fight_1"
48
#define ART_RESET0 "menu/art/reset_0"
49
#define ART_RESET1 "menu/art/reset_1"
50
#define ART_CUSTOM0 "menu/art/skirmish_0"
51
#define ART_CUSTOM1 "menu/art/skirmish_1"
53
#define ID_LEFTARROW 10
54
#define ID_PICTURE0 11
55
#define ID_PICTURE1 12
56
#define ID_PICTURE2 13
57
#define ID_PICTURE3 14
58
#define ID_RIGHTARROW 15
59
#define ID_PLAYERPIC 16
72
#define AWARDS_Y (PLAYER_Y + 26)
77
menutext_s item_banner;
78
menubitmap_s item_leftarrow;
79
menubitmap_s item_maps[4];
80
menubitmap_s item_rightarrow;
81
menubitmap_s item_player;
82
menubitmap_s item_awards[6];
83
menubitmap_s item_back;
84
menubitmap_s item_reset;
85
menubitmap_s item_custom;
86
menubitmap_s item_next;
87
menubitmap_s item_null;
91
const char * selectedArenaInfo;
93
char levelPicNames[4][MAX_QPATH];
94
char levelNames[4][16];
96
int levelScoresSkill[4];
97
qhandle_t levelSelectedPic;
98
qhandle_t levelFocusPic;
99
qhandle_t levelCompletePic[5];
101
char playerModel[MAX_QPATH];
102
char playerPicName[MAX_QPATH];
104
sfxHandle_t awardSounds[6];
107
qhandle_t botPics[7];
108
char botNames[7][10];
111
static levelMenuInfo_t levelMenuInfo;
113
static int selectedArenaSet;
114
static int selectedArena;
115
static int currentSet;
116
static int currentGame;
117
static int trainingTier;
118
static int finalTier;
128
static void PlayerIcon( const char *modelAndSkin, char *iconName, int iconNameMaxSize ) {
130
char model[MAX_QPATH];
132
Q_strncpyz( model, modelAndSkin, sizeof(model));
133
skin = Q_strrchr( model, '/' );
141
Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_%s.tga", model, skin );
143
if( !trap_R_RegisterShaderNoMip( iconName ) && Q_stricmp( skin, "default" ) != 0 ) {
144
Com_sprintf(iconName, iconNameMaxSize, "models/players/%s/icon_default.tga", model );
154
static qhandle_t PlayerIconHandle( const char *modelAndSkin ) {
155
char iconName[MAX_QPATH];
157
PlayerIcon( modelAndSkin, iconName, sizeof(iconName) );
158
return trap_R_RegisterShaderNoMip( iconName );
164
UI_SPLevelMenu_SetBots
167
static void UI_SPLevelMenu_SetBots( void ) {
171
char bots[MAX_INFO_STRING];
173
levelMenuInfo.numBots = 0;
174
if ( selectedArenaSet > currentSet ) {
178
Q_strncpyz( bots, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "bots" ), sizeof(bots) );
181
while( *p && levelMenuInfo.numBots < 7 ) {
183
while( *p && *p == ' ' ) {
190
// mark start of bot name
193
// skip until space of null
194
while( *p && *p != ' ' ) {
201
botInfo = UI_GetBotInfoByName( bot );
203
levelMenuInfo.botPics[levelMenuInfo.numBots] = PlayerIconHandle( Info_ValueForKey( botInfo, "model" ) );
204
Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], Info_ValueForKey( botInfo, "name" ), 10 );
207
levelMenuInfo.botPics[levelMenuInfo.numBots] = 0;
208
Q_strncpyz( levelMenuInfo.botNames[levelMenuInfo.numBots], bot, 10 );
210
Q_CleanStr( levelMenuInfo.botNames[levelMenuInfo.numBots] );
211
levelMenuInfo.numBots++;
218
UI_SPLevelMenu_SetMenuItems
221
static void UI_SPLevelMenu_SetMenuArena( int n, int level, const char *arenaInfo ) {
224
Q_strncpyz( map, Info_ValueForKey( arenaInfo, "map" ), sizeof(map) );
226
Q_strncpyz( levelMenuInfo.levelNames[n], map, sizeof(levelMenuInfo.levelNames[n]) );
227
Q_strupr( levelMenuInfo.levelNames[n] );
229
UI_GetBestScore( level, &levelMenuInfo.levelScores[n], &levelMenuInfo.levelScoresSkill[n] );
230
if( levelMenuInfo.levelScores[n] > 8 ) {
231
levelMenuInfo.levelScores[n] = 8;
234
strcpy( levelMenuInfo.levelPicNames[n], va( "levelshots/%s.tga", map ) );
235
if( !trap_R_RegisterShaderNoMip( levelMenuInfo.levelPicNames[n] ) ) {
236
strcpy( levelMenuInfo.levelPicNames[n], ART_MAP_UNKNOWN );
238
levelMenuInfo.item_maps[n].shader = 0;
239
if ( selectedArenaSet > currentSet ) {
240
levelMenuInfo.item_maps[n].generic.flags |= QMF_GRAYED;
243
levelMenuInfo.item_maps[n].generic.flags &= ~QMF_GRAYED;
246
levelMenuInfo.item_maps[n].generic.flags &= ~QMF_INACTIVE;
249
static void UI_SPLevelMenu_SetMenuItems( void ) {
252
const char *arenaInfo;
254
if ( selectedArenaSet > currentSet ) {
257
else if ( selectedArena == -1 ) {
261
if( selectedArenaSet == trainingTier || selectedArenaSet == finalTier ) {
265
if( selectedArena != -1 ) {
266
trap_Cvar_SetValue( "ui_spSelection", selectedArenaSet * ARENAS_PER_TIER + selectedArena );
269
if( selectedArenaSet == trainingTier ) {
270
arenaInfo = UI_GetSpecialArenaInfo( "training" );
271
level = atoi( Info_ValueForKey( arenaInfo, "num" ) );
272
UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo );
273
levelMenuInfo.selectedArenaInfo = arenaInfo;
275
levelMenuInfo.item_maps[0].generic.x = 256;
276
Bitmap_Init( &levelMenuInfo.item_maps[0] );
277
levelMenuInfo.item_maps[0].generic.bottom += 32;
278
levelMenuInfo.numMaps = 1;
280
levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE;
281
levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE;
282
levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE;
283
levelMenuInfo.levelPicNames[1][0] = 0;
284
levelMenuInfo.levelPicNames[2][0] = 0;
285
levelMenuInfo.levelPicNames[3][0] = 0;
286
levelMenuInfo.item_maps[1].shader = 0;
287
levelMenuInfo.item_maps[2].shader = 0;
288
levelMenuInfo.item_maps[3].shader = 0;
290
else if( selectedArenaSet == finalTier ) {
291
arenaInfo = UI_GetSpecialArenaInfo( "final" );
292
level = atoi( Info_ValueForKey( arenaInfo, "num" ) );
293
UI_SPLevelMenu_SetMenuArena( 0, level, arenaInfo );
294
levelMenuInfo.selectedArenaInfo = arenaInfo;
296
levelMenuInfo.item_maps[0].generic.x = 256;
297
Bitmap_Init( &levelMenuInfo.item_maps[0] );
298
levelMenuInfo.item_maps[0].generic.bottom += 32;
299
levelMenuInfo.numMaps = 1;
301
levelMenuInfo.item_maps[1].generic.flags |= QMF_INACTIVE;
302
levelMenuInfo.item_maps[2].generic.flags |= QMF_INACTIVE;
303
levelMenuInfo.item_maps[3].generic.flags |= QMF_INACTIVE;
304
levelMenuInfo.levelPicNames[1][0] = 0;
305
levelMenuInfo.levelPicNames[2][0] = 0;
306
levelMenuInfo.levelPicNames[3][0] = 0;
307
levelMenuInfo.item_maps[1].shader = 0;
308
levelMenuInfo.item_maps[2].shader = 0;
309
levelMenuInfo.item_maps[3].shader = 0;
312
levelMenuInfo.item_maps[0].generic.x = 46;
313
Bitmap_Init( &levelMenuInfo.item_maps[0] );
314
levelMenuInfo.item_maps[0].generic.bottom += 18;
315
levelMenuInfo.numMaps = 4;
317
for ( n = 0; n < 4; n++ ) {
318
level = selectedArenaSet * ARENAS_PER_TIER + n;
319
arenaInfo = UI_GetArenaInfoByNumber( level );
320
UI_SPLevelMenu_SetMenuArena( n, level, arenaInfo );
323
if( selectedArena != -1 ) {
324
levelMenuInfo.selectedArenaInfo = UI_GetArenaInfoByNumber( selectedArenaSet * ARENAS_PER_TIER + selectedArena );
328
// enable/disable arrows when they are valid/invalid
329
if ( selectedArenaSet == minTier ) {
330
levelMenuInfo.item_leftarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN );
333
levelMenuInfo.item_leftarrow.generic.flags &= ~( QMF_INACTIVE | QMF_HIDDEN );
336
if ( selectedArenaSet == maxTier ) {
337
levelMenuInfo.item_rightarrow.generic.flags |= ( QMF_INACTIVE | QMF_HIDDEN );
340
levelMenuInfo.item_rightarrow.generic.flags &= ~( QMF_INACTIVE | QMF_HIDDEN );
343
UI_SPLevelMenu_SetBots();
349
UI_SPLevelMenu_ResetEvent
352
static void UI_SPLevelMenu_ResetDraw( void ) {
353
UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This resets all of the", UI_CENTER|UI_SMALLFONT, color_yellow );
354
UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "single player game variables.", UI_CENTER|UI_SMALLFONT, color_yellow );
355
UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 2, "Do this only if you want to", UI_CENTER|UI_SMALLFONT, color_yellow );
356
UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 3, "start over from the beginning.", UI_CENTER|UI_SMALLFONT, color_yellow );
359
static void UI_SPLevelMenu_ResetAction( qboolean result ) {
364
// clear game variables
366
trap_Cvar_SetValue( "ui_spSelection", -4 );
368
// make the level select menu re-initialize
373
static void UI_SPLevelMenu_ResetEvent( void* ptr, int event )
375
if (event != QM_ACTIVATED) {
379
UI_ConfirmMenu( "RESET GAME?", UI_SPLevelMenu_ResetDraw, UI_SPLevelMenu_ResetAction );
385
UI_SPLevelMenu_LevelEvent
388
static void UI_SPLevelMenu_LevelEvent( void* ptr, int notification ) {
389
if (notification != QM_ACTIVATED) {
393
if ( selectedArenaSet == trainingTier || selectedArenaSet == finalTier ) {
397
selectedArena = ((menucommon_s*)ptr)->id - ID_PICTURE0;
398
levelMenuInfo.selectedArenaInfo = UI_GetArenaInfoByNumber( selectedArenaSet * ARENAS_PER_TIER + selectedArena );
399
UI_SPLevelMenu_SetBots();
401
trap_Cvar_SetValue( "ui_spSelection", selectedArenaSet * ARENAS_PER_TIER + selectedArena );
407
UI_SPLevelMenu_LeftArrowEvent
410
static void UI_SPLevelMenu_LeftArrowEvent( void* ptr, int notification ) {
411
if (notification != QM_ACTIVATED) {
415
if ( selectedArenaSet == minTier ) {
420
UI_SPLevelMenu_SetMenuItems();
426
UI_SPLevelMenu_RightArrowEvent
429
static void UI_SPLevelMenu_RightArrowEvent( void* ptr, int notification ) {
430
if (notification != QM_ACTIVATED) {
434
if ( selectedArenaSet == maxTier ) {
439
UI_SPLevelMenu_SetMenuItems();
445
UI_SPLevelMenu_PlayerEvent
448
static void UI_SPLevelMenu_PlayerEvent( void* ptr, int notification ) {
449
if (notification != QM_ACTIVATED) {
453
UI_PlayerSettingsMenu();
459
UI_SPLevelMenu_AwardEvent
462
static void UI_SPLevelMenu_AwardEvent( void* ptr, int notification ) {
465
if (notification != QM_ACTIVATED) {
469
n = ((menucommon_s*)ptr)->id - ID_AWARD1;
470
trap_S_StartLocalSound( levelMenuInfo.awardSounds[n], CHAN_ANNOUNCER );
476
UI_SPLevelMenu_NextEvent
479
static void UI_SPLevelMenu_NextEvent( void* ptr, int notification ) {
480
if (notification != QM_ACTIVATED) {
484
if ( selectedArenaSet > currentSet ) {
488
if ( selectedArena == -1 ) {
492
UI_SPSkillMenu( levelMenuInfo.selectedArenaInfo );
498
UI_SPLevelMenu_BackEvent
501
static void UI_SPLevelMenu_BackEvent( void* ptr, int notification ) {
502
if (notification != QM_ACTIVATED) {
506
if ( selectedArena == -1 ) {
516
UI_SPLevelMenu_CustomEvent
519
static void UI_SPLevelMenu_CustomEvent( void* ptr, int notification ) {
520
if (notification != QM_ACTIVATED) {
524
UI_StartServerMenu( qfalse );
530
UI_SPLevelMenu_MenuDraw
533
#define LEVEL_DESC_LEFT_MARGIN 332
535
static void UI_SPLevelMenu_MenuDraw( void ) {
542
char buf[MAX_INFO_VALUE];
545
if( levelMenuInfo.reinit ) {
552
trap_Cvar_VariableStringBuffer( "name", string, 32 );
553
Q_CleanStr( string );
554
UI_DrawProportionalString( 320, PLAYER_Y, string, UI_CENTER|UI_SMALLFONT, color_orange );
556
// check for model changes
557
trap_Cvar_VariableStringBuffer( "model", buf, sizeof(buf) );
558
if( Q_stricmp( buf, levelMenuInfo.playerModel ) != 0 ) {
559
Q_strncpyz( levelMenuInfo.playerModel, buf, sizeof(levelMenuInfo.playerModel) );
560
PlayerIcon( levelMenuInfo.playerModel, levelMenuInfo.playerPicName, sizeof(levelMenuInfo.playerPicName) );
561
levelMenuInfo.item_player.shader = 0;
564
// standard menu drawing
565
Menu_Draw( &levelMenuInfo.menu );
567
// draw player award levels
570
for( n = 0; n < 6; n++ ) {
571
level = levelMenuInfo.awardLevels[n];
574
x = 224 - (i - 1 ) / 2 * (48 + 16);
577
x = 368 + i / 2 * (48 + 16);
585
if( level >= 1000000 ) {
586
Com_sprintf( string, sizeof(string), "%im", level / 1000000 );
588
else if( level >= 1000 ) {
589
Com_sprintf( string, sizeof(string), "%ik", level / 1000 );
592
Com_sprintf( string, sizeof(string), "%i", level );
595
UI_DrawString( x + 24, y + 48, string, UI_CENTER, color_yellow );
599
UI_DrawProportionalString( 18, 38, va( "Tier %i", selectedArenaSet + 1 ), UI_LEFT|UI_SMALLFONT, color_orange );
601
for ( n = 0; n < levelMenuInfo.numMaps; n++ ) {
602
x = levelMenuInfo.item_maps[n].generic.x;
603
y = levelMenuInfo.item_maps[n].generic.y;
604
UI_FillRect( x, y + 96, 128, 18, color_black );
607
if ( selectedArenaSet > currentSet ) {
608
UI_DrawProportionalString( 320, 216, "ACCESS DENIED", UI_CENTER|UI_BIGFONT, color_red );
612
// show levelshots for levels of current tier
613
Vector4Copy( color_white, color );
614
color[3] = 0.5+0.5*sin(uis.realtime/PULSE_DIVISOR);
615
for ( n = 0; n < levelMenuInfo.numMaps; n++ ) {
616
x = levelMenuInfo.item_maps[n].generic.x;
617
y = levelMenuInfo.item_maps[n].generic.y;
619
UI_DrawString( x + 64, y + 96, levelMenuInfo.levelNames[n], UI_CENTER|UI_SMALLFONT, color_orange );
621
if( levelMenuInfo.levelScores[n] == 1 ) {
622
UI_DrawHandlePic( x, y, 128, 96, levelMenuInfo.levelCompletePic[levelMenuInfo.levelScoresSkill[n] - 1] );
625
if ( n == selectedArena ) {
626
if( Menu_ItemAtCursor( &levelMenuInfo.menu ) == &levelMenuInfo.item_maps[n] ) {
627
trap_R_SetColor( color );
629
UI_DrawHandlePic( x-1, y-1, 130, 130 - 14, levelMenuInfo.levelSelectedPic );
630
trap_R_SetColor( NULL );
632
else if( Menu_ItemAtCursor( &levelMenuInfo.menu ) == &levelMenuInfo.item_maps[n] ) {
633
trap_R_SetColor( color );
634
UI_DrawHandlePic( x-31, y-30, 256, 256-27, levelMenuInfo.levelFocusPic);
635
trap_R_SetColor( NULL );
639
// show map name and long name of selected level
641
Q_strncpyz( buf, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "map" ), 20 );
643
Com_sprintf( string, sizeof(string), "%s: %s", buf, Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "longname" ) );
644
UI_DrawProportionalString( 320, y, string, UI_CENTER|UI_SMALLFONT, color_orange );
646
// fraglimit = atoi( Info_ValueForKey( levelMenuInfo.selectedArenaInfo, "fraglimit" ) );
647
// UI_DrawString( 18, 212, va("Frags %i", fraglimit) , UI_LEFT|UI_SMALLFONT, color_orange );
649
// draw bot opponents
651
pad = (7 - levelMenuInfo.numBots) * (64 + 26) / 2;
652
for( n = 0; n < levelMenuInfo.numBots; n++ ) {
653
x = 18 + pad + (64 + 26) * n;
654
if( levelMenuInfo.botPics[n] ) {
655
UI_DrawHandlePic( x, y, 64, 64, levelMenuInfo.botPics[n]);
658
UI_FillRect( x, y, 64, 64, color_black );
659
UI_DrawProportionalString( x+22, y+18, "?", UI_BIGFONT, color_orange );
661
UI_DrawString( x, y + 64, levelMenuInfo.botNames[n], UI_SMALLFONT|UI_LEFT, color_orange );
671
void UI_SPLevelMenu_Cache( void ) {
674
trap_R_RegisterShaderNoMip( ART_LEVELFRAME_FOCUS );
675
trap_R_RegisterShaderNoMip( ART_LEVELFRAME_SELECTED );
676
trap_R_RegisterShaderNoMip( ART_ARROW );
677
trap_R_RegisterShaderNoMip( ART_ARROW_FOCUS );
678
trap_R_RegisterShaderNoMip( ART_MAP_UNKNOWN );
679
trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 );
680
trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 );
681
trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 );
682
trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 );
683
trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 );
684
trap_R_RegisterShaderNoMip( ART_BACK0 );
685
trap_R_RegisterShaderNoMip( ART_BACK1 );
686
trap_R_RegisterShaderNoMip( ART_FIGHT0 );
687
trap_R_RegisterShaderNoMip( ART_FIGHT1 );
688
trap_R_RegisterShaderNoMip( ART_RESET0 );
689
trap_R_RegisterShaderNoMip( ART_RESET1 );
690
trap_R_RegisterShaderNoMip( ART_CUSTOM0 );
691
trap_R_RegisterShaderNoMip( ART_CUSTOM1 );
693
for( n = 0; n < 6; n++ ) {
694
trap_R_RegisterShaderNoMip( ui_medalPicNames[n] );
695
levelMenuInfo.awardSounds[n] = trap_S_RegisterSound( ui_medalSounds[n], qfalse );
698
levelMenuInfo.levelSelectedPic = trap_R_RegisterShaderNoMip( ART_LEVELFRAME_SELECTED );
699
levelMenuInfo.levelFocusPic = trap_R_RegisterShaderNoMip( ART_LEVELFRAME_FOCUS );
700
levelMenuInfo.levelCompletePic[0] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE1 );
701
levelMenuInfo.levelCompletePic[1] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE2 );
702
levelMenuInfo.levelCompletePic[2] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE3 );
703
levelMenuInfo.levelCompletePic[3] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE4 );
704
levelMenuInfo.levelCompletePic[4] = trap_R_RegisterShaderNoMip( ART_MAP_COMPLETE5 );
713
static void UI_SPLevelMenu_Init( void ) {
720
skill = (int)trap_Cvar_VariableValue( "g_spSkill" );
721
if( skill < 1 || skill > 5 ) {
722
trap_Cvar_Set( "g_spSkill", "2" );
726
memset( &levelMenuInfo, 0, sizeof(levelMenuInfo) );
727
levelMenuInfo.menu.fullscreen = qtrue;
728
levelMenuInfo.menu.wrapAround = qtrue;
729
levelMenuInfo.menu.draw = UI_SPLevelMenu_MenuDraw;
731
UI_SPLevelMenu_Cache();
733
levelMenuInfo.item_banner.generic.type = MTYPE_BTEXT;
734
levelMenuInfo.item_banner.generic.x = 320;
735
levelMenuInfo.item_banner.generic.y = 16;
736
levelMenuInfo.item_banner.string = "CHOOSE LEVEL";
737
levelMenuInfo.item_banner.color = color_red;
738
levelMenuInfo.item_banner.style = UI_CENTER;
740
levelMenuInfo.item_leftarrow.generic.type = MTYPE_BITMAP;
741
levelMenuInfo.item_leftarrow.generic.name = ART_ARROW;
742
levelMenuInfo.item_leftarrow.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
743
levelMenuInfo.item_leftarrow.generic.x = 18;
744
levelMenuInfo.item_leftarrow.generic.y = 64;
745
levelMenuInfo.item_leftarrow.generic.callback = UI_SPLevelMenu_LeftArrowEvent;
746
levelMenuInfo.item_leftarrow.generic.id = ID_LEFTARROW;
747
levelMenuInfo.item_leftarrow.width = 16;
748
levelMenuInfo.item_leftarrow.height = 114;
749
levelMenuInfo.item_leftarrow.focuspic = ART_ARROW_FOCUS;
751
levelMenuInfo.item_maps[0].generic.type = MTYPE_BITMAP;
752
levelMenuInfo.item_maps[0].generic.name = levelMenuInfo.levelPicNames[0];
753
levelMenuInfo.item_maps[0].generic.flags = QMF_LEFT_JUSTIFY;
754
levelMenuInfo.item_maps[0].generic.x = 46;
755
levelMenuInfo.item_maps[0].generic.y = 64;
756
levelMenuInfo.item_maps[0].generic.id = ID_PICTURE0;
757
levelMenuInfo.item_maps[0].generic.callback = UI_SPLevelMenu_LevelEvent;
758
levelMenuInfo.item_maps[0].width = 128;
759
levelMenuInfo.item_maps[0].height = 96;
761
levelMenuInfo.item_maps[1].generic.type = MTYPE_BITMAP;
762
levelMenuInfo.item_maps[1].generic.name = levelMenuInfo.levelPicNames[1];
763
levelMenuInfo.item_maps[1].generic.flags = QMF_LEFT_JUSTIFY;
764
levelMenuInfo.item_maps[1].generic.x = 186;
765
levelMenuInfo.item_maps[1].generic.y = 64;
766
levelMenuInfo.item_maps[1].generic.id = ID_PICTURE1;
767
levelMenuInfo.item_maps[1].generic.callback = UI_SPLevelMenu_LevelEvent;
768
levelMenuInfo.item_maps[1].width = 128;
769
levelMenuInfo.item_maps[1].height = 96;
771
levelMenuInfo.item_maps[2].generic.type = MTYPE_BITMAP;
772
levelMenuInfo.item_maps[2].generic.name = levelMenuInfo.levelPicNames[2];
773
levelMenuInfo.item_maps[2].generic.flags = QMF_LEFT_JUSTIFY;
774
levelMenuInfo.item_maps[2].generic.x = 326;
775
levelMenuInfo.item_maps[2].generic.y = 64;
776
levelMenuInfo.item_maps[2].generic.id = ID_PICTURE2;
777
levelMenuInfo.item_maps[2].generic.callback = UI_SPLevelMenu_LevelEvent;
778
levelMenuInfo.item_maps[2].width = 128;
779
levelMenuInfo.item_maps[2].height = 96;
781
levelMenuInfo.item_maps[3].generic.type = MTYPE_BITMAP;
782
levelMenuInfo.item_maps[3].generic.name = levelMenuInfo.levelPicNames[3];
783
levelMenuInfo.item_maps[3].generic.flags = QMF_LEFT_JUSTIFY;
784
levelMenuInfo.item_maps[3].generic.x = 466;
785
levelMenuInfo.item_maps[3].generic.y = 64;
786
levelMenuInfo.item_maps[3].generic.id = ID_PICTURE3;
787
levelMenuInfo.item_maps[3].generic.callback = UI_SPLevelMenu_LevelEvent;
788
levelMenuInfo.item_maps[3].width = 128;
789
levelMenuInfo.item_maps[3].height = 96;
791
levelMenuInfo.item_rightarrow.generic.type = MTYPE_BITMAP;
792
levelMenuInfo.item_rightarrow.generic.name = ART_ARROW;
793
levelMenuInfo.item_rightarrow.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
794
levelMenuInfo.item_rightarrow.generic.x = 606;
795
levelMenuInfo.item_rightarrow.generic.y = 64;
796
levelMenuInfo.item_rightarrow.generic.callback = UI_SPLevelMenu_RightArrowEvent;
797
levelMenuInfo.item_rightarrow.generic.id = ID_RIGHTARROW;
798
levelMenuInfo.item_rightarrow.width = -16;
799
levelMenuInfo.item_rightarrow.height = 114;
800
levelMenuInfo.item_rightarrow.focuspic = ART_ARROW_FOCUS;
802
trap_Cvar_VariableStringBuffer( "model", levelMenuInfo.playerModel, sizeof(levelMenuInfo.playerModel) );
803
PlayerIcon( levelMenuInfo.playerModel, levelMenuInfo.playerPicName, sizeof(levelMenuInfo.playerPicName) );
804
levelMenuInfo.item_player.generic.type = MTYPE_BITMAP;
805
levelMenuInfo.item_player.generic.name = levelMenuInfo.playerPicName;
806
levelMenuInfo.item_player.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY;
807
levelMenuInfo.item_player.generic.x = 288;
808
levelMenuInfo.item_player.generic.y = AWARDS_Y;
809
levelMenuInfo.item_player.generic.id = ID_PLAYERPIC;
810
levelMenuInfo.item_player.generic.callback = UI_SPLevelMenu_PlayerEvent;
811
levelMenuInfo.item_player.width = 64;
812
levelMenuInfo.item_player.height = 64;
814
for( n = 0; n < 6; n++ ) {
815
levelMenuInfo.awardLevels[n] = UI_GetAwardLevel( n );
817
levelMenuInfo.awardLevels[AWARD_FRAGS] = 100 * (levelMenuInfo.awardLevels[AWARD_FRAGS] / 100);
821
for( n = 0; n < 6; n++ ) {
822
if( levelMenuInfo.awardLevels[n] ) {
824
x = 224 - (count - 1 ) / 2 * (48 + 16);
827
x = 368 + count / 2 * (48 + 16);
830
levelMenuInfo.item_awards[count].generic.type = MTYPE_BITMAP;
831
levelMenuInfo.item_awards[count].generic.name = ui_medalPicNames[n];
832
levelMenuInfo.item_awards[count].generic.flags = QMF_LEFT_JUSTIFY|QMF_SILENT|QMF_MOUSEONLY;
833
levelMenuInfo.item_awards[count].generic.x = x;
834
levelMenuInfo.item_awards[count].generic.y = y;
835
levelMenuInfo.item_awards[count].generic.id = ID_AWARD1 + n;
836
levelMenuInfo.item_awards[count].generic.callback = UI_SPLevelMenu_AwardEvent;
837
levelMenuInfo.item_awards[count].width = 48;
838
levelMenuInfo.item_awards[count].height = 48;
843
levelMenuInfo.item_back.generic.type = MTYPE_BITMAP;
844
levelMenuInfo.item_back.generic.name = ART_BACK0;
845
levelMenuInfo.item_back.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
846
levelMenuInfo.item_back.generic.x = 0;
847
levelMenuInfo.item_back.generic.y = 480-64;
848
levelMenuInfo.item_back.generic.callback = UI_SPLevelMenu_BackEvent;
849
levelMenuInfo.item_back.generic.id = ID_BACK;
850
levelMenuInfo.item_back.width = 128;
851
levelMenuInfo.item_back.height = 64;
852
levelMenuInfo.item_back.focuspic = ART_BACK1;
854
levelMenuInfo.item_reset.generic.type = MTYPE_BITMAP;
855
levelMenuInfo.item_reset.generic.name = ART_RESET0;
856
levelMenuInfo.item_reset.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
857
levelMenuInfo.item_reset.generic.x = 170;
858
levelMenuInfo.item_reset.generic.y = 480-64;
859
levelMenuInfo.item_reset.generic.callback = UI_SPLevelMenu_ResetEvent;
860
levelMenuInfo.item_reset.generic.id = ID_RESET;
861
levelMenuInfo.item_reset.width = 128;
862
levelMenuInfo.item_reset.height = 64;
863
levelMenuInfo.item_reset.focuspic = ART_RESET1;
865
levelMenuInfo.item_custom.generic.type = MTYPE_BITMAP;
866
levelMenuInfo.item_custom.generic.name = ART_CUSTOM0;
867
levelMenuInfo.item_custom.generic.flags = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
868
levelMenuInfo.item_custom.generic.x = 342;
869
levelMenuInfo.item_custom.generic.y = 480-64;
870
levelMenuInfo.item_custom.generic.callback = UI_SPLevelMenu_CustomEvent;
871
levelMenuInfo.item_custom.generic.id = ID_CUSTOM;
872
levelMenuInfo.item_custom.width = 128;
873
levelMenuInfo.item_custom.height = 64;
874
levelMenuInfo.item_custom.focuspic = ART_CUSTOM1;
876
levelMenuInfo.item_next.generic.type = MTYPE_BITMAP;
877
levelMenuInfo.item_next.generic.name = ART_FIGHT0;
878
levelMenuInfo.item_next.generic.flags = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
879
levelMenuInfo.item_next.generic.x = 640;
880
levelMenuInfo.item_next.generic.y = 480-64;
881
levelMenuInfo.item_next.generic.callback = UI_SPLevelMenu_NextEvent;
882
levelMenuInfo.item_next.generic.id = ID_NEXT;
883
levelMenuInfo.item_next.width = 128;
884
levelMenuInfo.item_next.height = 64;
885
levelMenuInfo.item_next.focuspic = ART_FIGHT1;
887
levelMenuInfo.item_null.generic.type = MTYPE_BITMAP;
888
levelMenuInfo.item_null.generic.flags = QMF_LEFT_JUSTIFY|QMF_MOUSEONLY|QMF_SILENT;
889
levelMenuInfo.item_null.generic.x = 0;
890
levelMenuInfo.item_null.generic.y = 0;
891
levelMenuInfo.item_null.width = 640;
892
levelMenuInfo.item_null.height = 480;
894
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_banner );
896
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_leftarrow );
897
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[0] );
898
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[1] );
899
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[2] );
900
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_maps[3] );
901
levelMenuInfo.item_maps[0].generic.bottom += 18;
902
levelMenuInfo.item_maps[1].generic.bottom += 18;
903
levelMenuInfo.item_maps[2].generic.bottom += 18;
904
levelMenuInfo.item_maps[3].generic.bottom += 18;
905
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_rightarrow );
907
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_player );
909
for( n = 0; n < count; n++ ) {
910
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_awards[n] );
912
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_back );
913
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_reset );
914
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_custom );
915
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_next );
916
Menu_AddItem( &levelMenuInfo.menu, &levelMenuInfo.item_null );
918
trap_Cvar_VariableStringBuffer( "ui_spSelection", buf, sizeof(buf) );
921
selectedArenaSet = n / ARENAS_PER_TIER;
922
selectedArena = n % ARENAS_PER_TIER;
925
selectedArenaSet = currentSet;
926
selectedArena = currentGame;
929
UI_SPLevelMenu_SetMenuItems();
938
void UI_SPLevelMenu( void ) {
941
const char *arenaInfo;
944
arenaInfo = UI_GetSpecialArenaInfo( "training" );
946
minTier = trainingTier;
947
trainingLevel = atoi( Info_ValueForKey( arenaInfo, "num" ) );
954
finalTier = UI_GetNumSPTiers();
955
arenaInfo = UI_GetSpecialArenaInfo( "final" );
960
maxTier = finalTier - 1;
961
if( maxTier < minTier ) {
966
level = UI_GetCurrentGame();
968
level = UI_GetNumSPArenas() - 1;
969
if( maxTier == finalTier ) {
974
if( level == trainingLevel ) {
979
currentSet = level / ARENAS_PER_TIER;
980
currentGame = level % ARENAS_PER_TIER;
983
UI_SPLevelMenu_Init();
984
UI_PushMenu( &levelMenuInfo.menu );
985
Menu_SetCursorToItem( &levelMenuInfo.menu, &levelMenuInfo.item_next );
994
void UI_SPLevelMenu_f( void ) {
995
trap_Key_SetCatcher( KEYCATCH_UI );
1003
UI_SPLevelMenu_ReInit
1006
void UI_SPLevelMenu_ReInit( void ) {
1007
levelMenuInfo.reinit = qtrue;