Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

ui_menu.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 ===========================================================================
00021 */
00022 //
00023 /*
00024 =======================================================================
00025 
00026 MAIN MENU
00027 
00028 =======================================================================
00029 */
00030 
00031 
00032 #include "ui_local.h"
00033 
00034 
00035 #define ID_SINGLEPLAYER         10
00036 #define ID_MULTIPLAYER          11
00037 #define ID_SETUP                12
00038 #define ID_DEMOS                13
00039 #define ID_CINEMATICS           14
00040 #define ID_TEAMARENA        15
00041 #define ID_MODS                 16
00042 #define ID_EXIT                 17
00043 
00044 #define MAIN_BANNER_MODEL               "models/mapobjects/banner/banner5.md3"
00045 #define MAIN_MENU_VERTICAL_SPACING      34
00046 
00047 
00048 typedef struct {
00049     menuframework_s menu;
00050 
00051     menutext_s      singleplayer;
00052     menutext_s      multiplayer;
00053     menutext_s      setup;
00054     menutext_s      demos;
00055     menutext_s      cinematics;
00056     menutext_s      teamArena;
00057     menutext_s      mods;
00058     menutext_s      exit;
00059 
00060     qhandle_t       bannerModel;
00061 } mainmenu_t;
00062 
00063 
00064 static mainmenu_t s_main;
00065 
00066 typedef struct {
00067     menuframework_s menu;   
00068     char errorMessage[4096];
00069 } errorMessage_t;
00070 
00071 static errorMessage_t s_errorMessage;
00072 
00073 /*
00074 =================
00075 MainMenu_ExitAction
00076 =================
00077 */
00078 static void MainMenu_ExitAction( qboolean result ) {
00079     if( !result ) {
00080         return;
00081     }
00082     UI_PopMenu();
00083     UI_CreditMenu();
00084 }
00085 
00086 
00087 
00088 /*
00089 =================
00090 Main_MenuEvent
00091 =================
00092 */
00093 void Main_MenuEvent (void* ptr, int event) {
00094     if( event != QM_ACTIVATED ) {
00095         return;
00096     }
00097 
00098     switch( ((menucommon_s*)ptr)->id ) {
00099     case ID_SINGLEPLAYER:
00100         UI_SPLevelMenu();
00101         break;
00102 
00103     case ID_MULTIPLAYER:
00104         UI_ArenaServersMenu();
00105         break;
00106 
00107     case ID_SETUP:
00108         UI_SetupMenu();
00109         break;
00110 
00111     case ID_DEMOS:
00112         UI_DemosMenu();
00113         break;
00114 
00115     case ID_CINEMATICS:
00116         UI_CinematicsMenu();
00117         break;
00118 
00119     case ID_MODS:
00120         UI_ModsMenu();
00121         break;
00122 
00123     case ID_TEAMARENA:
00124         trap_Cvar_Set( "fs_game", "missionpack");
00125         trap_Cmd_ExecuteText( EXEC_APPEND, "vid_restart;" );
00126         break;
00127 
00128     case ID_EXIT:
00129         UI_ConfirmMenu( "EXIT GAME?", NULL, MainMenu_ExitAction );
00130         break;
00131     }
00132 }
00133 
00134 
00135 /*
00136 ===============
00137 MainMenu_Cache
00138 ===============
00139 */
00140 void MainMenu_Cache( void ) {
00141     s_main.bannerModel = trap_R_RegisterModel( MAIN_BANNER_MODEL );
00142 }
00143 
00144 sfxHandle_t ErrorMessage_Key(int key)
00145 {
00146     trap_Cvar_Set( "com_errorMessage", "" );
00147     UI_MainMenu();
00148     return (menu_null_sound);
00149 }
00150 
00151 /*
00152 ===============
00153 Main_MenuDraw
00154 TTimo: this function is common to the main menu and errorMessage menu
00155 ===============
00156 */
00157 
00158 static void Main_MenuDraw( void ) {
00159     refdef_t        refdef;
00160     refEntity_t     ent;
00161     vec3_t          origin;
00162     vec3_t          angles;
00163     float           adjust;
00164     float           x, y, w, h;
00165     vec4_t          color = {0.5, 0, 0, 1};
00166 
00167     // setup the refdef
00168 
00169     memset( &refdef, 0, sizeof( refdef ) );
00170 
00171     refdef.rdflags = RDF_NOWORLDMODEL;
00172 
00173     AxisClear( refdef.viewaxis );
00174 
00175     x = 0;
00176     y = 0;
00177     w = 640;
00178     h = 120;
00179     UI_AdjustFrom640( &x, &y, &w, &h );
00180     refdef.x = x;
00181     refdef.y = y;
00182     refdef.width = w;
00183     refdef.height = h;
00184 
00185     adjust = 0; // JDC: Kenneth asked me to stop this 1.0 * sin( (float)uis.realtime / 1000 );
00186     refdef.fov_x = 60 + adjust;
00187     refdef.fov_y = 19.6875 + adjust;
00188 
00189     refdef.time = uis.realtime;
00190 
00191     origin[0] = 300;
00192     origin[1] = 0;
00193     origin[2] = -32;
00194 
00195     trap_R_ClearScene();
00196 
00197     // add the model
00198 
00199     memset( &ent, 0, sizeof(ent) );
00200 
00201     adjust = 5.0 * sin( (float)uis.realtime / 5000 );
00202     VectorSet( angles, 0, 180 + adjust, 0 );
00203     AnglesToAxis( angles, ent.axis );
00204     ent.hModel = s_main.bannerModel;
00205     VectorCopy( origin, ent.origin );
00206     VectorCopy( origin, ent.lightingOrigin );
00207     ent.renderfx = RF_LIGHTING_ORIGIN | RF_NOSHADOW;
00208     VectorCopy( ent.origin, ent.oldorigin );
00209 
00210     trap_R_AddRefEntityToScene( &ent );
00211 
00212     trap_R_RenderScene( &refdef );
00213     
00214     if (strlen(s_errorMessage.errorMessage))
00215     {
00216         UI_DrawProportionalString_AutoWrapped( 320, 192, 600, 20, s_errorMessage.errorMessage, UI_CENTER|UI_SMALLFONT|UI_DROPSHADOW, menu_text_color );
00217     }
00218     else
00219     {
00220         // standard menu drawing
00221         Menu_Draw( &s_main.menu );      
00222     }
00223 
00224     if (uis.demoversion) {
00225         UI_DrawProportionalString( 320, 372, "DEMO      FOR MATURE AUDIENCES      DEMO", UI_CENTER|UI_SMALLFONT, color );
00226         UI_DrawString( 320, 400, "Quake III Arena(c) 1999-2000, Id Software, Inc.  All Rights Reserved", UI_CENTER|UI_SMALLFONT, color );
00227     } else {
00228         UI_DrawString( 320, 450, "Quake III Arena(c) 1999-2000, Id Software, Inc.  All Rights Reserved", UI_CENTER|UI_SMALLFONT, color );
00229     }
00230 }
00231 
00232 
00233 /*
00234 ===============
00235 UI_TeamArenaExists
00236 ===============
00237 */
00238 static qboolean UI_TeamArenaExists( void ) {
00239     int     numdirs;
00240     char    dirlist[2048];
00241     char    *dirptr;
00242   char  *descptr;
00243     int     i;
00244     int     dirlen;
00245 
00246     numdirs = trap_FS_GetFileList( "$modlist", "", dirlist, sizeof(dirlist) );
00247     dirptr  = dirlist;
00248     for( i = 0; i < numdirs; i++ ) {
00249         dirlen = strlen( dirptr ) + 1;
00250     descptr = dirptr + dirlen;
00251         if (Q_stricmp(dirptr, "missionpack") == 0) {
00252             return qtrue;
00253         }
00254     dirptr += dirlen + strlen(descptr) + 1;
00255     }
00256     return qfalse;
00257 }
00258 
00259 
00260 /*
00261 ===============
00262 UI_MainMenu
00263 
00264 The main menu only comes up when not in a game,
00265 so make sure that the attract loop server is down
00266 and that local cinematics are killed
00267 ===============
00268 */
00269 void UI_MainMenu( void ) {
00270     int     y;
00271     qboolean teamArena = qfalse;
00272     int     style = UI_CENTER | UI_DROPSHADOW;
00273 
00274     trap_Cvar_Set( "sv_killserver", "1" );
00275 
00276     if( !uis.demoversion && !ui_cdkeychecked.integer ) {
00277         char    key[17];
00278 
00279         trap_GetCDKey( key, sizeof(key) );
00280         if( trap_VerifyCDKey( key, NULL ) == qfalse ) {
00281             UI_CDKeyMenu();
00282             return;
00283         }
00284     }
00285     
00286     memset( &s_main, 0 ,sizeof(mainmenu_t) );
00287     memset( &s_errorMessage, 0 ,sizeof(errorMessage_t) );
00288 
00289     // com_errorMessage would need that too
00290     MainMenu_Cache();
00291     
00292     trap_Cvar_VariableStringBuffer( "com_errorMessage", s_errorMessage.errorMessage, sizeof(s_errorMessage.errorMessage) );
00293     if (strlen(s_errorMessage.errorMessage))
00294     {   
00295         s_errorMessage.menu.draw = Main_MenuDraw;
00296         s_errorMessage.menu.key = ErrorMessage_Key;
00297         s_errorMessage.menu.fullscreen = qtrue;
00298         s_errorMessage.menu.wrapAround = qtrue;
00299         s_errorMessage.menu.showlogo = qtrue;       
00300 
00301         trap_Key_SetCatcher( KEYCATCH_UI );
00302         uis.menusp = 0;
00303         UI_PushMenu ( &s_errorMessage.menu );
00304         
00305         return;
00306     }
00307 
00308     s_main.menu.draw = Main_MenuDraw;
00309     s_main.menu.fullscreen = qtrue;
00310     s_main.menu.wrapAround = qtrue;
00311     s_main.menu.showlogo = qtrue;
00312 
00313     y = 134;
00314     s_main.singleplayer.generic.type        = MTYPE_PTEXT;
00315     s_main.singleplayer.generic.flags       = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00316     s_main.singleplayer.generic.x           = 320;
00317     s_main.singleplayer.generic.y           = y;
00318     s_main.singleplayer.generic.id          = ID_SINGLEPLAYER;
00319     s_main.singleplayer.generic.callback    = Main_MenuEvent; 
00320     s_main.singleplayer.string              = "SINGLE PLAYER";
00321     s_main.singleplayer.color               = color_red;
00322     s_main.singleplayer.style               = style;
00323 
00324     y += MAIN_MENU_VERTICAL_SPACING;
00325     s_main.multiplayer.generic.type         = MTYPE_PTEXT;
00326     s_main.multiplayer.generic.flags        = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00327     s_main.multiplayer.generic.x            = 320;
00328     s_main.multiplayer.generic.y            = y;
00329     s_main.multiplayer.generic.id           = ID_MULTIPLAYER;
00330     s_main.multiplayer.generic.callback     = Main_MenuEvent; 
00331     s_main.multiplayer.string               = "MULTIPLAYER";
00332     s_main.multiplayer.color                = color_red;
00333     s_main.multiplayer.style                = style;
00334 
00335     y += MAIN_MENU_VERTICAL_SPACING;
00336     s_main.setup.generic.type               = MTYPE_PTEXT;
00337     s_main.setup.generic.flags              = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00338     s_main.setup.generic.x                  = 320;
00339     s_main.setup.generic.y                  = y;
00340     s_main.setup.generic.id                 = ID_SETUP;
00341     s_main.setup.generic.callback           = Main_MenuEvent; 
00342     s_main.setup.string                     = "SETUP";
00343     s_main.setup.color                      = color_red;
00344     s_main.setup.style                      = style;
00345 
00346     y += MAIN_MENU_VERTICAL_SPACING;
00347     s_main.demos.generic.type               = MTYPE_PTEXT;
00348     s_main.demos.generic.flags              = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00349     s_main.demos.generic.x                  = 320;
00350     s_main.demos.generic.y                  = y;
00351     s_main.demos.generic.id                 = ID_DEMOS;
00352     s_main.demos.generic.callback           = Main_MenuEvent; 
00353     s_main.demos.string                     = "DEMOS";
00354     s_main.demos.color                      = color_red;
00355     s_main.demos.style                      = style;
00356 
00357     y += MAIN_MENU_VERTICAL_SPACING;
00358     s_main.cinematics.generic.type          = MTYPE_PTEXT;
00359     s_main.cinematics.generic.flags         = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00360     s_main.cinematics.generic.x             = 320;
00361     s_main.cinematics.generic.y             = y;
00362     s_main.cinematics.generic.id            = ID_CINEMATICS;
00363     s_main.cinematics.generic.callback      = Main_MenuEvent; 
00364     s_main.cinematics.string                = "CINEMATICS";
00365     s_main.cinematics.color                 = color_red;
00366     s_main.cinematics.style                 = style;
00367 
00368     if (UI_TeamArenaExists()) {
00369         teamArena = qtrue;
00370         y += MAIN_MENU_VERTICAL_SPACING;
00371         s_main.teamArena.generic.type           = MTYPE_PTEXT;
00372         s_main.teamArena.generic.flags          = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00373         s_main.teamArena.generic.x              = 320;
00374         s_main.teamArena.generic.y              = y;
00375         s_main.teamArena.generic.id             = ID_TEAMARENA;
00376         s_main.teamArena.generic.callback       = Main_MenuEvent; 
00377         s_main.teamArena.string                 = "TEAM ARENA";
00378         s_main.teamArena.color                  = color_red;
00379         s_main.teamArena.style                  = style;
00380     }
00381 
00382     y += MAIN_MENU_VERTICAL_SPACING;
00383     s_main.mods.generic.type            = MTYPE_PTEXT;
00384     s_main.mods.generic.flags           = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00385     s_main.mods.generic.x               = 320;
00386     s_main.mods.generic.y               = y;
00387     s_main.mods.generic.id              = ID_MODS;
00388     s_main.mods.generic.callback        = Main_MenuEvent; 
00389     s_main.mods.string                  = "MODS";
00390     s_main.mods.color                   = color_red;
00391     s_main.mods.style                   = style;
00392 
00393     y += MAIN_MENU_VERTICAL_SPACING;
00394     s_main.exit.generic.type                = MTYPE_PTEXT;
00395     s_main.exit.generic.flags               = QMF_CENTER_JUSTIFY|QMF_PULSEIFFOCUS;
00396     s_main.exit.generic.x                   = 320;
00397     s_main.exit.generic.y                   = y;
00398     s_main.exit.generic.id                  = ID_EXIT;
00399     s_main.exit.generic.callback            = Main_MenuEvent; 
00400     s_main.exit.string                      = "EXIT";
00401     s_main.exit.color                       = color_red;
00402     s_main.exit.style                       = style;
00403 
00404     Menu_AddItem( &s_main.menu, &s_main.singleplayer );
00405     Menu_AddItem( &s_main.menu, &s_main.multiplayer );
00406     Menu_AddItem( &s_main.menu, &s_main.setup );
00407     Menu_AddItem( &s_main.menu, &s_main.demos );
00408     Menu_AddItem( &s_main.menu, &s_main.cinematics );
00409     if (teamArena) {
00410         Menu_AddItem( &s_main.menu, &s_main.teamArena );
00411     }
00412     Menu_AddItem( &s_main.menu, &s_main.mods );
00413     Menu_AddItem( &s_main.menu, &s_main.exit );             
00414 
00415     trap_Key_SetCatcher( KEYCATCH_UI );
00416     uis.menusp = 0;
00417     UI_PushMenu ( &s_main.menu );
00418         
00419 }

Generated on Thu Aug 25 12:37:42 2005 for Quake III Arena by  doxygen 1.3.9.1