doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Session_menu.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "Session_local.h"
33 
35 
36 // implements the setup for, and commands from, the main menu
37 
38 /*
39 ==============
40 idSessionLocal::GetActiveMenu
41 ==============
42 */
44  return guiActive;
45 }
46 
47 /*
48 ==============
49 idSessionLocal::StartMainMenu
50 ==============
51 */
52 void idSessionLocal::StartMenu( bool playIntro ) {
53  if ( guiActive == guiMainMenu ) {
54  return;
55  }
56 
57  if ( readDemo ) {
58  // if we're playing a demo, esc kills it
59  UnloadMap();
60  }
61 
62  // pause the game sound world
63  if ( sw != NULL && !sw->IsPaused() ) {
64  sw->Pause();
65  }
66 
67  // start playing the menu sounds
69 
71  guiMainMenu->HandleNamedEvent( playIntro ? "playIntro" : "noIntro" );
72 
73 
74  if(fileSystem->HasD3XP()) {
75  guiMainMenu->SetStateString("game_list", common->GetLanguageDict()->GetString( "#str_07202" ));
76  } else {
77  guiMainMenu->SetStateString("game_list", common->GetLanguageDict()->GetString( "#str_07212" ));
78  }
79 
80  console->Close();
81 
82 }
83 
84 /*
85 =================
86 idSessionLocal::SetGUI
87 =================
88 */
90  const char *cmd;
91 
92  guiActive = gui;
93  guiHandle = handle;
94  if ( guiMsgRestore ) {
95  common->DPrintf( "idSessionLocal::SetGUI: cleared an active message box\n" );
97  }
98  if ( !guiActive ) {
99  return;
100  }
101 
102  if ( guiActive == guiMainMenu ) {
105  } else if ( guiActive == guiRestartMenu ) {
107  }
108 
109  sysEvent_t ev;
110  memset( &ev, 0, sizeof( ev ) );
111  ev.evType = SE_NONE;
112 
113  cmd = guiActive->HandleEvent( &ev, com_frameTime );
114  guiActive->Activate( true, com_frameTime );
115 }
116 
117 /*
118 ===============
119 idSessionLocal::ExitMenu
120 ===============
121 */
123  guiActive = NULL;
124 
125  // go back to the game sounds
127 
128  // unpause the game sound world
129  if ( sw != NULL && sw->IsPaused() ) {
130  sw->UnPause();
131  }
132 }
133 
134 /*
135 ===============
136 idListSaveGameCompare
137 ===============
138 */
139 ID_INLINE int idListSaveGameCompare( const fileTIME_T *a, const fileTIME_T *b ) {
140  return b->timeStamp - a->timeStamp;
141 }
142 
143 /*
144 ===============
145 idSessionLocal::GetSaveGameList
146 ===============
147 */
149  int i;
150  idFileList *files;
151 
152  // NOTE: no fs_game_base for savegames
153  idStr game = cvarSystem->GetCVarString( "fs_game" );
154  if( game.Length() ) {
155  files = fileSystem->ListFiles( "savegames", ".save", false, false, game );
156  } else {
157  files = fileSystem->ListFiles( "savegames", ".save" );
158  }
159 
160  fileList = files->GetList();
161  fileSystem->FreeFileList( files );
162 
163  for ( i = 0; i < fileList.Num(); i++ ) {
164  ID_TIME_T timeStamp;
165 
166  fileSystem->ReadFile( "savegames/" + fileList[i], NULL, &timeStamp );
167  fileList[i].StripLeading( '/' );
168  fileList[i].StripFileExtension();
169 
170  fileTIME_T ft;
171  ft.index = i;
172  ft.timeStamp = timeStamp;
173  fileTimes.Append( ft );
174  }
175 
176  fileTimes.Sort( idListSaveGameCompare );
177 }
178 
179 /*
180 ===============
181 idSessionLocal::SetSaveGameGuiVars
182 ===============
183 */
185  int i;
186  idStr name;
187  idStrList fileList;
188  idList<fileTIME_T> fileTimes;
189 
191  fileList.Clear();
192  fileTimes.Clear();
193 
194  GetSaveGameList( fileList, fileTimes );
195 
196  loadGameList.SetNum( fileList.Num() );
197  for ( i = 0; i < fileList.Num(); i++ ) {
198  loadGameList[i] = fileList[fileTimes[i].index];
199 
201  if ( src.LoadFile( va("savegames/%s.txt", loadGameList[i].c_str()) ) ) {
202  idToken tok;
203  src.ReadToken( &tok );
204  name = tok;
205  } else {
206  name = loadGameList[i];
207  }
208 
209  name += "\t";
210 
211  idStr date = Sys_TimeStampToStr( fileTimes[i].timeStamp );
212  name += date;
213 
214  guiActive->SetStateString( va("loadgame_item_%i", i), name);
215  }
216  guiActive->DeleteStateVar( va("loadgame_item_%i", fileList.Num()) );
217 
218  guiActive->SetStateString( "loadgame_sel_0", "-1" );
219  guiActive->SetStateString( "loadgame_shot", "guis/assets/blankLevelShot" );
220 
221 }
222 
223 /*
224 ===============
225 idSessionLocal::SetModsMenuGuiVars
226 ===============
227 */
229  int i;
230  idModList *list = fileSystem->ListMods();
231 
232  modsList.SetNum( list->GetNumMods() );
233 
234  // Build the gui list
235  for ( i = 0; i < list->GetNumMods(); i++ ) {
236  guiActive->SetStateString( va("modsList_item_%i", i), list->GetDescription( i ) );
237  modsList[i] = list->GetMod( i );
238  }
239  guiActive->DeleteStateVar( va("modsList_item_%i", list->GetNumMods()) );
240  guiActive->SetStateString( "modsList_sel_0", "-1" );
241 
242  fileSystem->FreeModList( list );
243 }
244 
245 
246 /*
247 ===============
248 idSessionLocal::SetMainMenuSkin
249 ===============
250 */
252  // skins
253  idStr str = cvarSystem->GetCVarString( "mod_validSkins" );
254  idStr uiSkin = cvarSystem->GetCVarString( "ui_skin" );
255  idStr skin;
256  int skinId = 1;
257  int count = 1;
258  while ( str.Length() ) {
259  int n = str.Find( ";" );
260  if ( n >= 0 ) {
261  skin = str.Left( n );
262  str = str.Right( str.Length() - n - 1 );
263  } else {
264  skin = str;
265  str = "";
266  }
267  if ( skin.Icmp( uiSkin ) == 0 ) {
268  skinId = count;
269  }
270  count++;
271  }
272 
273  for ( int i = 0; i < count; i++ ) {
274  guiMainMenu->SetStateInt( va( "skin%i", i+1 ), 0 );
275  }
276  guiMainMenu->SetStateInt( va( "skin%i", skinId ), 1 );
277 }
278 
279 /*
280 ===============
281 idSessionLocal::SetPbMenuGuiVars
282 ===============
283 */
285 }
286 
287 /*
288 ===============
289 idSessionLocal::SetMainMenuGuiVars
290 ===============
291 */
293 
294  guiMainMenu->SetStateString( "serverlist_sel_0", "-1" );
295  guiMainMenu->SetStateString( "serverlist_selid_0", "-1" );
296 
297  guiMainMenu->SetStateInt( "com_machineSpec", com_machineSpec.GetInteger() );
298 
299  // "inetGame" will hold a hand-typed inet address, which is not archived to a cvar
300  guiMainMenu->SetStateString( "inetGame", "" );
301 
302  // key bind names
304 
305  // flag for in-game menu
306  if ( mapSpawned ) {
307  guiMainMenu->SetStateString( "inGame", IsMultiplayer() ? "2" : "1" );
308  } else {
309  guiMainMenu->SetStateString( "inGame", "0" );
310  }
311 
312  SetCDKeyGuiVars( );
313 #ifdef ID_DEMO_BUILD
314  guiMainMenu->SetStateString( "nightmare", "0" );
315 #else
316  guiMainMenu->SetStateString( "nightmare", cvarSystem->GetCVarBool( "g_nightmare" ) ? "1" : "0" );
317 #endif
318  guiMainMenu->SetStateString( "browser_levelshot", "guis/assets/splash/pdtempa" );
319 
320  SetMainMenuSkin();
321  // Mods Menu
323 
324  guiMsg->SetStateString( "visible_hasxp", fileSystem->HasD3XP() ? "1" : "0" );
325 
326 #if defined( __linux__ )
327  guiMainMenu->SetStateString( "driver_prompt", "1" );
328 #else
329  guiMainMenu->SetStateString( "driver_prompt", "0" );
330 #endif
331 
333 }
334 
335 /*
336 ==============
337 idSessionLocal::HandleSaveGameMenuCommands
338 ==============
339 */
341 
342  const char *cmd = args.Argv(icmd-1);
343 
344  if ( !idStr::Icmp( cmd, "loadGame" ) ) {
345  int choice = guiActive->State().GetInt("loadgame_sel_0");
346  if ( choice >= 0 && choice < loadGameList.Num() ) {
347  sessLocal.LoadGame( loadGameList[choice] );
348  }
349  return true;
350  }
351 
352  if ( !idStr::Icmp( cmd, "saveGame" ) ) {
353  const char *saveGameName = guiActive->State().GetString("saveGameName");
354  if ( saveGameName && saveGameName[0] ) {
355 
356  // First see if the file already exists unless they pass '1' to authorize the overwrite
357  if ( icmd == args.Argc() || atoi(args.Argv( icmd++ )) == 0 ) {
358  idStr saveFileName = saveGameName;
359  sessLocal.ScrubSaveGameFileName( saveFileName );
360  saveFileName = "savegames/" + saveFileName;
361  saveFileName.SetFileExtension(".save");
362 
363  idStr game = cvarSystem->GetCVarString( "fs_game" );
364  idFile *file;
365  if(game.Length()) {
366  file = fileSystem->OpenFileRead( saveFileName, true, game );
367  } else {
368  file = fileSystem->OpenFileRead( saveFileName );
369  }
370 
371  if ( file != NULL ) {
372  fileSystem->CloseFile( file );
373 
374  // The file exists, see if it's an autosave
375  saveFileName.SetFileExtension(".txt");
377  if ( src.LoadFile( saveFileName ) ) {
378  idToken tok;
379  src.ReadToken( &tok ); // Name
380  src.ReadToken( &tok ); // Map
381  src.ReadToken( &tok ); // Screenshot
382  if ( !tok.IsEmpty() ) {
383  // NOTE: base/ gui doesn't handle that one
384  guiActive->HandleNamedEvent( "autosaveOverwriteError" );
385  return true;
386  }
387  }
388  guiActive->HandleNamedEvent( "saveGameOverwrite" );
389  return true;
390  }
391  }
392 
393  sessLocal.SaveGame( saveGameName );
396  }
397  return true;
398  }
399 
400  if ( !idStr::Icmp( cmd, "deleteGame" ) ) {
401  int choice = guiActive->State().GetInt( "loadgame_sel_0" );
402  if ( choice >= 0 && choice < loadGameList.Num() ) {
403  fileSystem->RemoveFile( va("savegames/%s.save", loadGameList[choice].c_str()) );
404  fileSystem->RemoveFile( va("savegames/%s.tga", loadGameList[choice].c_str()) );
405  fileSystem->RemoveFile( va("savegames/%s.txt", loadGameList[choice].c_str()) );
408  }
409  return true;
410  }
411 
412  if ( !idStr::Icmp( cmd, "updateSaveGameInfo" ) ) {
413  int choice = guiActive->State().GetInt( "loadgame_sel_0" );
414  if ( choice >= 0 && choice < loadGameList.Num() ) {
415  const idMaterial *material;
416 
417  idStr saveName, description, screenshot;
419  if ( src.LoadFile( va("savegames/%s.txt", loadGameList[choice].c_str()) ) ) {
420  idToken tok;
421 
422  src.ReadToken( &tok );
423  saveName = tok;
424 
425  src.ReadToken( &tok );
426  description = tok;
427 
428  src.ReadToken( &tok );
429  screenshot = tok;
430 
431  } else {
432  saveName = loadGameList[choice];
433  description = loadGameList[choice];
434  screenshot = "";
435  }
436  if ( screenshot.Length() == 0 ) {
437  screenshot = va("savegames/%s.tga", loadGameList[choice].c_str());
438  }
439  material = declManager->FindMaterial( screenshot );
440  if ( material ) {
441  material->ReloadImages( false );
442  }
443  guiActive->SetStateString( "loadgame_shot", screenshot );
444 
445  saveName.RemoveColors();
446  guiActive->SetStateString( "saveGameName", saveName );
447  guiActive->SetStateString( "saveGameDescription", description );
448 
449  ID_TIME_T timeStamp;
450  fileSystem->ReadFile( va("savegames/%s.save", loadGameList[choice].c_str()), NULL, &timeStamp );
451  idStr date = Sys_TimeStampToStr(timeStamp);
452  int tab = date.Find( '\t' );
453  idStr time = date.Right( date.Length() - tab - 1);
454  guiActive->SetStateString( "saveGameDate", date.Left( tab ) );
455  guiActive->SetStateString( "saveGameTime", time );
456  }
457  return true;
458  }
459 
460  return false;
461 }
462 
463 /*
464 ==============
465 idSessionLocal::HandleRestartMenuCommands
466 
467 Executes any commands returned by the gui
468 ==============
469 */
470 void idSessionLocal::HandleRestartMenuCommands( const char *menuCommand ) {
471  // execute the command from the menu
472  int icmd;
473  idCmdArgs args;
474 
475  args.TokenizeString( menuCommand, false );
476 
477  for( icmd = 0; icmd < args.Argc(); ) {
478  const char *cmd = args.Argv( icmd++ );
479 
480  if ( HandleSaveGameMenuCommand( args, icmd ) ) {
481  continue;
482  }
483 
484  if ( !idStr::Icmp( cmd, "restart" ) ) {
485  if ( !LoadGame( GetAutoSaveName( mapSpawnData.serverInfo.GetString("si_map") ) ) ) {
486  // If we can't load the autosave then just restart the map
488  }
489  continue;
490  }
491 
492  if ( !idStr::Icmp( cmd, "quit" ) ) {
493  ExitMenu();
494  common->Quit();
495  return;
496  }
497 
498  if ( !idStr::Icmp ( cmd, "exec" ) ) {
499  cmdSystem->BufferCommandText( CMD_EXEC_APPEND, args.Argv( icmd++ ) );
500  continue;
501  }
502 
503  if ( !idStr::Icmp( cmd, "play" ) ) {
504  if ( args.Argc() - icmd >= 1 ) {
505  idStr snd = args.Argv(icmd++);
506  sw->PlayShaderDirectly(snd);
507  }
508  continue;
509  }
510  }
511 }
512 
513 /*
514 ==============
515 idSessionLocal::HandleIntroMenuCommands
516 
517 Executes any commands returned by the gui
518 ==============
519 */
520 void idSessionLocal::HandleIntroMenuCommands( const char *menuCommand ) {
521  // execute the command from the menu
522  int i;
523  idCmdArgs args;
524 
525  args.TokenizeString( menuCommand, false );
526 
527  for( i = 0; i < args.Argc(); ) {
528  const char *cmd = args.Argv( i++ );
529 
530  if ( !idStr::Icmp( cmd, "startGame" ) ) {
532  ExitMenu();
533  continue;
534  }
535 
536  if ( !idStr::Icmp( cmd, "play" ) ) {
537  if ( args.Argc() - i >= 1 ) {
538  idStr snd = args.Argv(i++);
540  }
541  continue;
542  }
543  }
544 }
545 
546 /*
547 ==============
548 idSessionLocal::UpdateMPLevelShot
549 ==============
550 */
552  char screenshot[ MAX_STRING_CHARS ];
554  guiMainMenu->SetStateString( "current_levelshot", screenshot );
555 }
556 
557 /*
558 ==============
559 idSessionLocal::HandleMainMenuCommands
560 
561 Executes any commands returned by the gui
562 ==============
563 */
564 void idSessionLocal::HandleMainMenuCommands( const char *menuCommand ) {
565  // execute the command from the menu
566  int icmd;
567  idCmdArgs args;
568 
569  args.TokenizeString( menuCommand, false );
570 
571  for( icmd = 0; icmd < args.Argc(); ) {
572  const char *cmd = args.Argv( icmd++ );
573 
574  if ( HandleSaveGameMenuCommand( args, icmd ) ) {
575  continue;
576  }
577 
578  // always let the game know the command is being run
579  if ( game ) {
581  }
582 
583  if ( !idStr::Icmp( cmd, "startGame" ) ) {
584  cvarSystem->SetCVarInteger( "g_skill", guiMainMenu->State().GetInt( "skill" ) );
585  if ( icmd < args.Argc() ) {
586  StartNewGame( args.Argv( icmd++ ) );
587  } else {
588 #ifndef ID_DEMO_BUILD
589  StartNewGame( "game/mars_city1" );
590 #else
591  StartNewGame( "game/demo_mars_city1" );
592 #endif
593  }
594  // need to do this here to make sure com_frameTime is correct or the gui activates with a time that
595  // is "however long map load took" time in the past
596  common->GUIFrame( false, false );
597  SetGUI( guiIntro, NULL );
599  // stop playing the game sounds
601 
602  continue;
603  }
604 
605  if ( !idStr::Icmp( cmd, "quit" ) ) {
606  ExitMenu();
607  common->Quit();
608  return;
609  }
610 
611  if ( !idStr::Icmp( cmd, "loadMod" ) ) {
612  int choice = guiActive->State().GetInt( "modsList_sel_0" );
613  if ( choice >= 0 && choice < modsList.Num() ) {
614  cvarSystem->SetCVarString( "fs_game", modsList[ choice ] );
615  cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "reloadEngine menu\n" );
616  }
617  }
618 
619  if ( !idStr::Icmp( cmd, "UpdateServers" ) ) {
620  if ( guiActive->State().GetBool( "lanSet" ) ) {
622  } else {
624  }
625  continue;
626  }
627 
628  if ( !idStr::Icmp( cmd, "RefreshServers" ) ) {
629  if ( guiActive->State().GetBool( "lanSet" ) ) {
631  } else {
633  }
634  continue;
635  }
636 
637  if ( !idStr::Icmp( cmd, "FilterServers" ) ) {
639  continue;
640  }
641 
642  if ( !idStr::Icmp( cmd, "sortServerName" ) ) {
644  continue;
645  }
646 
647  if ( !idStr::Icmp( cmd, "sortGame" ) ) {
649  continue;
650  }
651 
652  if ( !idStr::Icmp( cmd, "sortPlayers" ) ) {
654  continue;
655  }
656 
657  if ( !idStr::Icmp( cmd, "sortPing" ) ) {
659  continue;
660  }
661 
662  if ( !idStr::Icmp( cmd, "sortGameType" ) ) {
664  continue;
665  }
666 
667  if ( !idStr::Icmp( cmd, "sortMap" ) ) {
669  continue;
670  }
671 
672  if ( !idStr::Icmp( cmd, "serverList" ) ) {
674  continue;
675  }
676 
677  if ( !idStr::Icmp( cmd, "LANConnect" ) ) {
678  int sel = guiActive->State().GetInt( "serverList_selid_0" );
679  cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "Connect %d\n", sel ) );
680  return;
681  }
682 
683  if ( !idStr::Icmp( cmd, "MAPScan" ) ) {
684  const char *gametype = cvarSystem->GetCVarString( "si_gameType" );
685  if ( gametype == NULL || *gametype == 0 || idStr::Icmp( gametype, "singleplayer" ) == 0 ) {
686  gametype = "Deathmatch";
687  }
688 
689  int i, num;
690  idStr si_map = cvarSystem->GetCVarString("si_map");
691  const idDict *dict;
692 
695  num = fileSystem->GetNumMaps();
696  for ( i = 0; i < num; i++ ) {
697  dict = fileSystem->GetMapDecl( i );
698  if ( dict && dict->GetBool( gametype ) ) {
699  const char *mapName = dict->GetString( "name" );
700  if ( mapName[ 0 ] == '\0' ) {
701  mapName = dict->GetString( "path" );
702  }
703  mapName = common->GetLanguageDict()->GetString( mapName );
704  guiMainMenu_MapList->Add( i, mapName );
705  if ( !si_map.Icmp( dict->GetString( "path" ) ) ) {
707  }
708  }
709  }
711  if ( i >= 0 ) {
712  dict = fileSystem->GetMapDecl( i);
713  } else {
714  dict = NULL;
715  }
716  cvarSystem->SetCVarString( "si_map", ( dict ? dict->GetString( "path" ) : "" ) );
717 
718  // set the current level shot
720  continue;
721  }
722 
723  if ( !idStr::Icmp( cmd, "click_mapList" ) ) {
724  int mapNum = guiMainMenu_MapList->GetSelection( NULL, 0 );
725  const idDict *dict = fileSystem->GetMapDecl( mapNum );
726  if ( dict ) {
727  cvarSystem->SetCVarString( "si_map", dict->GetString( "path" ) );
728  }
730  continue;
731  }
732 
733  if ( !idStr::Icmp( cmd, "inetConnect" ) ) {
734  const char *s = guiMainMenu->State().GetString( "inetGame" );
735 
736  if ( !s || s[0] == 0 ) {
737  // don't put the menu away if there isn't a valid selection
738  continue;
739  }
740 
741  cmdSystem->BufferCommandText( CMD_EXEC_NOW, va( "connect %s", s ) );
742  return;
743  }
744 
745  if ( !idStr::Icmp( cmd, "startMultiplayer" ) ) {
746  int dedicated = guiActive->State().GetInt( "dedicated" );
747  cvarSystem->SetCVarBool( "net_LANServer", guiActive->State().GetBool( "server_type" ) );
748  if ( gui_configServerRate.GetInteger() > 0 ) {
749  // guess the best rate for upstream, number of internet clients
750  if ( gui_configServerRate.GetInteger() == 5 || cvarSystem->GetCVarBool( "net_LANServer" ) ) {
751  cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 25600 );
752  } else {
753  // internet players
754  int n_clients = cvarSystem->GetCVarInteger( "si_maxPlayers" );
755  if ( !dedicated ) {
756  n_clients--;
757  }
758  int maxclients = 0;
759  switch ( gui_configServerRate.GetInteger() ) {
760  case 1:
761  // 128 kbits
762  cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 8000 );
763  maxclients = 2;
764  break;
765  case 2:
766  // 256 kbits
767  cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 9500 );
768  maxclients = 3;
769  break;
770  case 3:
771  // 384 kbits
772  cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 10500 );
773  maxclients = 4;
774  break;
775  case 4:
776  // 512 and above..
777  cvarSystem->SetCVarInteger( "net_serverMaxClientRate", 14000 );
778  maxclients = 4;
779  break;
780  }
781  if ( n_clients > maxclients ) {
782  if ( MessageBox( MSG_OKCANCEL, va( common->GetLanguageDict()->GetString( "#str_04315" ), dedicated ? maxclients : Min( 8, maxclients + 1 ) ), common->GetLanguageDict()->GetString( "#str_04316" ), true, "OK" )[ 0 ] == '\0' ) {
783  continue;
784  }
785  cvarSystem->SetCVarInteger( "si_maxPlayers", dedicated ? maxclients : Min( 8, maxclients + 1 ) );
786  }
787  }
788  }
789 
790  if ( !dedicated && !cvarSystem->GetCVarBool( "net_LANServer" ) && cvarSystem->GetCVarInteger("si_maxPlayers") > 4 ) {
791  // "Dedicated server mode is recommended for internet servers with more than 4 players. Continue in listen mode?"
792  if ( !MessageBox( MSG_YESNO, common->GetLanguageDict()->GetString ( "#str_00100625" ), common->GetLanguageDict()->GetString ( "#str_00100626" ), true, "yes" )[ 0 ] ) {
793  continue;
794  }
795  }
796 
797  if ( dedicated ) {
798  cvarSystem->SetCVarInteger( "net_serverDedicated", 1 );
799  } else {
800  cvarSystem->SetCVarInteger( "net_serverDedicated", 0 );
801  }
802 
803 
804 
805  ExitMenu();
806  // may trigger a reloadEngine - APPEND
807  cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "SpawnServer\n" );
808  return;
809  }
810 
811  if ( !idStr::Icmp( cmd, "mpSkin")) {
812  idStr skin;
813  if ( args.Argc() - icmd >= 1 ) {
814  skin = args.Argv( icmd++ );
815  cvarSystem->SetCVarString( "ui_skin", skin );
816  SetMainMenuSkin();
817  }
818  continue;
819  }
820 
821  if ( !idStr::Icmp( cmd, "close" ) ) {
822  // if we aren't in a game, the menu can't be closed
823  if ( mapSpawned ) {
824  ExitMenu();
825  }
826  continue;
827  }
828 
829  if ( !idStr::Icmp( cmd, "resetdefaults" ) ) {
830  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "exec default.cfg" );
832  continue;
833  }
834 
835 
836  if ( !idStr::Icmp( cmd, "bind" ) ) {
837  if ( args.Argc() - icmd >= 2 ) {
838  int key = atoi( args.Argv( icmd++ ) );
839  idStr bind = args.Argv( icmd++ );
840  if ( idKeyInput::NumBinds( bind ) >= 2 && !idKeyInput::KeyIsBoundTo( key, bind ) ) {
842  }
843  idKeyInput::SetBinding( key, bind );
845  }
846  continue;
847  }
848 
849  if ( !idStr::Icmp( cmd, "play" ) ) {
850  if ( args.Argc() - icmd >= 1 ) {
851  idStr snd = args.Argv( icmd++ );
852  int channel = 1;
853  if ( snd.Length() == 1 ) {
854  channel = atoi( snd );
855  snd = args.Argv( icmd++ );
856  }
857  menuSoundWorld->PlayShaderDirectly( snd, channel );
858 
859  }
860  continue;
861  }
862 
863  if ( !idStr::Icmp( cmd, "music" ) ) {
864  if ( args.Argc() - icmd >= 1 ) {
865  idStr snd = args.Argv( icmd++ );
867  }
868  continue;
869  }
870 
871  // triggered from mainmenu or mpmain
872  if ( !idStr::Icmp( cmd, "sound" ) ) {
873  idStr vcmd;
874  if ( args.Argc() - icmd >= 1 ) {
875  vcmd = args.Argv( icmd++ );
876  }
877  if ( !vcmd.Length() || !vcmd.Icmp( "speakers" ) ) {
878  int old = cvarSystem->GetCVarInteger( "s_numberOfSpeakers" );
879  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "s_restart\n" );
880  if ( old != cvarSystem->GetCVarInteger( "s_numberOfSpeakers" ) ) {
881 #ifdef _WIN32
882  MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04142" ), common->GetLanguageDict()->GetString( "#str_04141" ), true );
883 #else
884  // a message that doesn't mention the windows control panel
885  MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07230" ), common->GetLanguageDict()->GetString( "#str_04141" ), true );
886 #endif
887  }
888  }
889  if ( !vcmd.Icmp( "eax" ) ) {
890  if ( cvarSystem->GetCVarBool( "s_useEAXReverb" ) ) {
891  int eax = soundSystem->IsEAXAvailable();
892  switch ( eax ) {
893  case 2:
894  // OpenAL subsystem load failed
895  MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07238" ), common->GetLanguageDict()->GetString( "#str_07231" ), true );
896  break;
897  case 1:
898  // when you restart
899  MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04137" ), common->GetLanguageDict()->GetString( "#str_07231" ), true );
900  break;
901  case -1:
902  cvarSystem->SetCVarBool( "s_useEAXReverb", false );
903  // disabled
904  MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07233" ), common->GetLanguageDict()->GetString( "#str_07231" ), true );
905  break;
906  case 0:
907  cvarSystem->SetCVarBool( "s_useEAXReverb", false );
908  // not available
909  MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_07232" ), common->GetLanguageDict()->GetString( "#str_07231" ), true );
910  break;
911  }
912  } else {
913  // also turn off OpenAL so we fully go back to legacy mixer
914  cvarSystem->SetCVarBool( "s_useOpenAL", false );
915  // when you restart
916  MessageBox( MSG_OK, common->GetLanguageDict()->GetString( "#str_04137" ), common->GetLanguageDict()->GetString( "#str_07231" ), true );
917  }
918  }
919  if ( !vcmd.Icmp( "drivar" ) ) {
920  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "s_restart\n" );
921  }
922  continue;
923  }
924 
925  if ( !idStr::Icmp( cmd, "video" ) ) {
926  idStr vcmd;
927  if ( args.Argc() - icmd >= 1 ) {
928  vcmd = args.Argv( icmd++ );
929  }
930 
931  int oldSpec = com_machineSpec.GetInteger();
932 
933  if ( idStr::Icmp( vcmd, "low" ) == 0 ) {
935  } else if ( idStr::Icmp( vcmd, "medium" ) == 0 ) {
937  } else if ( idStr::Icmp( vcmd, "high" ) == 0 ) {
939  } else if ( idStr::Icmp( vcmd, "ultra" ) == 0 ) {
941  } else if ( idStr::Icmp( vcmd, "recommended" ) == 0 ) {
942  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "setMachineSpec\n" );
943  }
944 
945  if ( oldSpec != com_machineSpec.GetInteger() ) {
946  guiActive->SetStateInt( "com_machineSpec", com_machineSpec.GetInteger() );
948  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "execMachineSpec\n" );
949  }
950 
951  if ( idStr::Icmp( vcmd, "restart" ) == 0) {
952  guiActive->HandleNamedEvent( "cvar write render" );
953  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "vid_restart\n" );
954  }
955 
956  continue;
957  }
958 
959  if ( !idStr::Icmp( cmd, "clearBind" ) ) {
960  if ( args.Argc() - icmd >= 1 ) {
961  idKeyInput::UnbindBinding( args.Argv( icmd++ ) );
963  }
964  continue;
965  }
966 
967  // FIXME: obsolete
968  if ( !idStr::Icmp( cmd, "chatdone" ) ) {
969  idStr temp = guiActive->State().GetString( "chattext" );
970  temp += "\r";
971  guiActive->SetStateString( "chattext", "" );
972  continue;
973  }
974 
975  if ( !idStr::Icmp ( cmd, "exec" ) ) {
976 
977  //Backup the language so we can restore it after defaults.
978  idStr lang = cvarSystem->GetCVarString("sys_lang");
979 
980  cmdSystem->BufferCommandText( CMD_EXEC_NOW, args.Argv( icmd++ ) );
981  if ( idStr::Icmp( "cvar_restart", args.Argv( icmd - 1 ) ) == 0 ) {
982  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "exec default.cfg" );
983  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "setMachineSpec\n" );
984 
985  //Make sure that any r_brightness changes take effect
986  float bright = cvarSystem->GetCVarFloat("r_brightness");
987  cvarSystem->SetCVarFloat("r_brightness", 0.0f);
988  cvarSystem->SetCVarFloat("r_brightness", bright);
989 
990  //Force user info modified after a reset to defaults
992 
993  guiActive->SetStateInt( "com_machineSpec", com_machineSpec.GetInteger() );
994 
995  //Restore the language
996  cvarSystem->SetCVarString("sys_lang", lang);
997 
998  }
999  continue;
1000  }
1001 
1002  if ( !idStr::Icmp ( cmd, "loadBinds" ) ) {
1004  continue;
1005  }
1006 
1007  if ( !idStr::Icmp( cmd, "systemCvars" ) ) {
1008  guiActive->HandleNamedEvent( "cvar read render" );
1009  guiActive->HandleNamedEvent( "cvar read sound" );
1010  continue;
1011  }
1012 
1013  if ( !idStr::Icmp( cmd, "SetCDKey" ) ) {
1014  // we can't do this from inside the HandleMainMenuCommands code, otherwise the message box stuff gets confused
1015  cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "promptKey\n" );
1016  continue;
1017  }
1018 
1019  if ( !idStr::Icmp( cmd, "CheckUpdate" ) ) {
1021  continue;
1022  }
1023 
1024  if ( !idStr::Icmp( cmd, "CheckUpdate2" ) ) {
1026  continue;
1027  }
1028 
1029  if ( !idStr::Icmp( cmd, "checkKeys" ) ) {
1030 #if ID_ENFORCE_KEY
1031  // not a strict check so you silently auth in the background without bugging the user
1032  if ( !session->CDKeysAreValid( false ) ) {
1033  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "promptKey force" );
1035  }
1036 #endif
1037  continue;
1038  }
1039 
1040  // triggered from mainmenu or mpmain
1041  if ( !idStr::Icmp( cmd, "punkbuster" ) ) {
1042  idStr vcmd;
1043  if ( args.Argc() - icmd >= 1 ) {
1044  vcmd = args.Argv( icmd++ );
1045  }
1046  // filtering PB based on enabled/disabled
1048  SetPbMenuGuiVars();
1049  continue;
1050  }
1051  }
1052 }
1053 
1054 /*
1055 ==============
1056 idSessionLocal::HandleChatMenuCommands
1057 
1058 Executes any commands returned by the gui
1059 ==============
1060 */
1061 void idSessionLocal::HandleChatMenuCommands( const char *menuCommand ) {
1062  // execute the command from the menu
1063  int i;
1064  idCmdArgs args;
1065 
1066  args.TokenizeString( menuCommand, false );
1067 
1068  for ( i = 0; i < args.Argc(); ) {
1069  const char *cmd = args.Argv( i++ );
1070 
1071  if ( idStr::Icmp( cmd, "chatactive" ) == 0 ) {
1072  //chat.chatMode = CHAT_GLOBAL;
1073  continue;
1074  }
1075  if ( idStr::Icmp( cmd, "chatabort" ) == 0 ) {
1076  //chat.chatMode = CHAT_NONE;
1077  continue;
1078  }
1079  if ( idStr::Icmp( cmd, "netready" ) == 0 ) {
1080  bool b = cvarSystem->GetCVarBool( "ui_ready" );
1081  cvarSystem->SetCVarBool( "ui_ready", !b );
1082  continue;
1083  }
1084  if ( idStr::Icmp( cmd, "netstart" ) == 0 ) {
1085  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "netcommand start\n" );
1086  continue;
1087  }
1088  }
1089 }
1090 
1091 /*
1092 ==============
1093 idSessionLocal::HandleInGameCommands
1094 
1095 Executes any commands returned by the gui
1096 ==============
1097 */
1098 void idSessionLocal::HandleInGameCommands( const char *menuCommand ) {
1099  // execute the command from the menu
1100  idCmdArgs args;
1101 
1102  args.TokenizeString( menuCommand, false );
1103 
1104  const char *cmd = args.Argv( 0 );
1105  if ( !idStr::Icmp( cmd, "close" ) ) {
1106  if ( guiActive ) {
1107  sysEvent_t ev;
1108  ev.evType = SE_NONE;
1109  const char *cmd;
1110  cmd = guiActive->HandleEvent( &ev, com_frameTime );
1111  guiActive->Activate( false, com_frameTime );
1112  guiActive = NULL;
1113  }
1114  }
1115 }
1116 
1117 /*
1118 ==============
1119 idSessionLocal::DispatchCommand
1120 ==============
1121 */
1122 void idSessionLocal::DispatchCommand( idUserInterface *gui, const char *menuCommand, bool doIngame ) {
1123 
1124  if ( !gui ) {
1125  gui = guiActive;
1126  }
1127 
1128  if ( gui == guiMainMenu ) {
1129  HandleMainMenuCommands( menuCommand );
1130  return;
1131  } else if ( gui == guiIntro) {
1132  HandleIntroMenuCommands( menuCommand );
1133  } else if ( gui == guiMsg ) {
1134  HandleMsgCommands( menuCommand );
1135  } else if ( gui == guiTakeNotes ) {
1136  HandleNoteCommands( menuCommand );
1137  } else if ( gui == guiRestartMenu ) {
1138  HandleRestartMenuCommands( menuCommand );
1139  } else if ( game && guiActive && guiActive->State().GetBool( "gameDraw" ) ) {
1140  const char *cmd = game->HandleGuiCommands( menuCommand );
1141  if ( !cmd ) {
1142  guiActive = NULL;
1143  } else if ( idStr::Icmp( cmd, "main" ) == 0 ) {
1144  StartMenu();
1145  } else if ( strstr( cmd, "sound " ) == cmd ) {
1146  // pipe the GUI sound commands not handled by the game to the main menu code
1147  HandleMainMenuCommands( cmd );
1148  }
1149  } else if ( guiHandle ) {
1150  if ( (*guiHandle)( menuCommand ) ) {
1151  return;
1152  }
1153  } else if ( !doIngame ) {
1154  common->DPrintf( "idSessionLocal::DispatchCommand: no dispatch found for command '%s'\n", menuCommand );
1155  }
1156 
1157  if ( doIngame ) {
1158  HandleInGameCommands( menuCommand );
1159  }
1160 }
1161 
1162 
1163 /*
1164 ==============
1165 idSessionLocal::MenuEvent
1166 
1167 Executes any commands returned by the gui
1168 ==============
1169 */
1171  const char *menuCommand;
1172 
1173  if ( guiActive == NULL ) {
1174  return;
1175  }
1176 
1177  menuCommand = guiActive->HandleEvent( event, com_frameTime );
1178 
1179  if ( !menuCommand || !menuCommand[0] ) {
1180  // If the menu didn't handle the event, and it's a key down event for an F key, run the bind
1181  if ( event->evType == SE_KEY && event->evValue2 == 1 && event->evValue >= K_F1 && event->evValue <= K_F12 ) {
1183  }
1184  return;
1185  }
1186 
1187  DispatchCommand( guiActive, menuCommand );
1188 }
1189 
1190 /*
1191 =================
1192 idSessionLocal::GuiFrameEvents
1193 =================
1194 */
1196  const char *cmd;
1197  sysEvent_t ev;
1198  idUserInterface *gui;
1199 
1200  // stop generating move and button commands when a local console or menu is active
1201  // running here so SP, async networking and no game all go through it
1202  if ( console->Active() || guiActive ) {
1204  } else {
1206  }
1207 
1208  if ( guiTest ) {
1209  gui = guiTest;
1210  } else if ( guiActive ) {
1211  gui = guiActive;
1212  } else {
1213  return;
1214  }
1215 
1216  memset( &ev, 0, sizeof( ev ) );
1217 
1218  ev.evType = SE_NONE;
1219  cmd = gui->HandleEvent( &ev, com_frameTime );
1220  if ( cmd && cmd[0] ) {
1221  DispatchCommand( guiActive, cmd );
1222  }
1223 }
1224 
1225 /*
1226 =================
1227 idSessionLocal::BoxDialogSanityCheck
1228 =================
1229 */
1231  if ( !common->IsInitialized() ) {
1232  common->DPrintf( "message box sanity check: !common->IsInitialized()\n" );
1233  return false;
1234  }
1235  if ( !guiMsg ) {
1236  return false;
1237  }
1238  if ( guiMsgRestore ) {
1239  common->DPrintf( "message box sanity check: recursed\n" );
1240  return false;
1241  }
1242  if ( cvarSystem->GetCVarInteger( "net_serverDedicated" ) ) {
1243  common->DPrintf( "message box sanity check: not compatible with dedicated server\n" );
1244  return false;
1245  }
1246  return true;
1247 }
1248 
1249 /*
1250 =================
1251 idSessionLocal::MessageBox
1252 =================
1253 */
1254 const char* idSessionLocal::MessageBox( msgBoxType_t type, const char *message, const char *title, bool wait, const char *fire_yes, const char *fire_no, bool network ) {
1255 
1256  common->DPrintf( "MessageBox: %s - %s\n", title ? title : "", message ? message : "" );
1257 
1258  if ( !BoxDialogSanityCheck() ) {
1259  return NULL;
1260  }
1261 
1262  guiMsg->SetStateString( "title", title ? title : "" );
1263  guiMsg->SetStateString( "message", message ? message : "" );
1264  if ( type == MSG_WAIT ) {
1265  guiMsg->SetStateString( "visible_msgbox", "0" );
1266  guiMsg->SetStateString( "visible_waitbox", "1" );
1267  } else {
1268  guiMsg->SetStateString( "visible_msgbox", "1" );
1269  guiMsg->SetStateString( "visible_waitbox", "0" );
1270  }
1271 
1272  guiMsg->SetStateString( "visible_entry", "0" );
1273  guiMsg->SetStateString( "visible_cdkey", "0" );
1274  switch ( type ) {
1275  case MSG_INFO:
1276  guiMsg->SetStateString( "mid", "" );
1277  guiMsg->SetStateString( "visible_mid", "0" );
1278  guiMsg->SetStateString( "visible_left", "0" );
1279  guiMsg->SetStateString( "visible_right", "0" );
1280  break;
1281  case MSG_OK:
1282  guiMsg->SetStateString( "mid", common->GetLanguageDict()->GetString( "#str_04339" ) );
1283  guiMsg->SetStateString( "visible_mid", "1" );
1284  guiMsg->SetStateString( "visible_left", "0" );
1285  guiMsg->SetStateString( "visible_right", "0" );
1286  break;
1287  case MSG_ABORT:
1288  guiMsg->SetStateString( "mid", common->GetLanguageDict()->GetString( "#str_04340" ) );
1289  guiMsg->SetStateString( "visible_mid", "1" );
1290  guiMsg->SetStateString( "visible_left", "0" );
1291  guiMsg->SetStateString( "visible_right", "0" );
1292  break;
1293  case MSG_OKCANCEL:
1294  guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04339" ) );
1295  guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04340" ) );
1296  guiMsg->SetStateString( "visible_mid", "0" );
1297  guiMsg->SetStateString( "visible_left", "1" );
1298  guiMsg->SetStateString( "visible_right", "1" );
1299  break;
1300  case MSG_YESNO:
1301  guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04341" ) );
1302  guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04342" ) );
1303  guiMsg->SetStateString( "visible_mid", "0" );
1304  guiMsg->SetStateString( "visible_left", "1" );
1305  guiMsg->SetStateString( "visible_right", "1" );
1306  break;
1307  case MSG_PROMPT:
1308  guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04339" ) );
1309  guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04340" ) );
1310  guiMsg->SetStateString( "visible_mid", "0" );
1311  guiMsg->SetStateString( "visible_left", "1" );
1312  guiMsg->SetStateString( "visible_right", "1" );
1313  guiMsg->SetStateString( "visible_entry", "1" );
1314  guiMsg->HandleNamedEvent( "Prompt" );
1315  break;
1316  case MSG_CDKEY:
1317  guiMsg->SetStateString( "left", common->GetLanguageDict()->GetString( "#str_04339" ) );
1318  guiMsg->SetStateString( "right", common->GetLanguageDict()->GetString( "#str_04340" ) );
1319  guiMsg->SetStateString( "visible_msgbox", "0" );
1320  guiMsg->SetStateString( "visible_cdkey", "1" );
1321  guiMsg->SetStateString( "visible_hasxp", fileSystem->HasD3XP() ? "1" : "0" );
1322  // the current cdkey / xpkey values may have bad/random data in them
1323  // it's best to avoid printing them completely, unless the key is good
1324  if ( cdkey_state == CDKEY_OK ) {
1325  guiMsg->SetStateString( "str_cdkey", cdkey );
1326  guiMsg->SetStateString( "visible_cdchk", "0" );
1327  } else {
1328  guiMsg->SetStateString( "str_cdkey", "" );
1329  guiMsg->SetStateString( "visible_cdchk", "1" );
1330  }
1331  guiMsg->SetStateString( "str_cdchk", "" );
1332  if ( xpkey_state == CDKEY_OK ) {
1333  guiMsg->SetStateString( "str_xpkey", xpkey );
1334  guiMsg->SetStateString( "visible_xpchk", "0" );
1335  } else {
1336  guiMsg->SetStateString( "str_xpkey", "" );
1337  guiMsg->SetStateString( "visible_xpchk", "1" );
1338  }
1339  guiMsg->SetStateString( "str_xpchk", "" );
1340  guiMsg->HandleNamedEvent( "CDKey" );
1341  break;
1342  case MSG_WAIT:
1343  break;
1344  default:
1345  common->Printf( "idSessionLocal::MessageBox: unknown msg box type\n" );
1346  }
1347  msgFireBack[ 0 ] = fire_yes ? fire_yes : "";
1348  msgFireBack[ 1 ] = fire_no ? fire_no : "";
1350  guiActive = guiMsg;
1351  guiMsg->SetCursor( 325, 290 );
1352  guiActive->Activate( true, com_frameTime );
1353  msgRunning = true;
1354  msgRetIndex = -1;
1355 
1356  if ( wait ) {
1357  // play one frame ignoring events so we don't get confused by parasite button releases
1358  msgIgnoreButtons = true;
1359  common->GUIFrame( true, network );
1360  msgIgnoreButtons = false;
1361  while ( msgRunning ) {
1362  common->GUIFrame( true, network );
1363  }
1364  if ( msgRetIndex < 0 ) {
1365  // MSG_WAIT and other StopBox calls
1366  return NULL;
1367  }
1368  if ( type == MSG_PROMPT ) {
1369  if ( msgRetIndex == 0 ) {
1370  guiMsg->State().GetString( "str_entry", "", msgFireBack[ 0 ] );
1371  return msgFireBack[ 0 ].c_str();
1372  } else {
1373  return NULL;
1374  }
1375  } else if ( type == MSG_CDKEY ) {
1376  if ( msgRetIndex == 0 ) {
1377  // the visible_ values distinguish looking at a valid key, or editing it
1378  sprintf( msgFireBack[ 0 ], "%1s;%16s;%2s;%1s;%16s;%2s",
1379  guiMsg->State().GetString( "visible_cdchk" ),
1380  guiMsg->State().GetString( "str_cdkey" ),
1381  guiMsg->State().GetString( "str_cdchk" ),
1382  guiMsg->State().GetString( "visible_xpchk" ),
1383  guiMsg->State().GetString( "str_xpkey" ),
1384  guiMsg->State().GetString( "str_xpchk" ) );
1385  return msgFireBack[ 0 ].c_str();
1386  } else {
1387  return NULL;
1388  }
1389  } else {
1390  return msgFireBack[ msgRetIndex ].c_str();
1391  }
1392  }
1393  return NULL;
1394 }
1395 
1396 /*
1397 =================
1398 idSessionLocal::DownloadProgressBox
1399 =================
1400 */
1401 void idSessionLocal::DownloadProgressBox( backgroundDownload_t *bgl, const char *title, int progress_start, int progress_end ) {
1402  int dlnow = 0, dltotal = 0;
1403  int startTime = Sys_Milliseconds();
1404  int lapsed;
1405  idStr sNow, sTotal, sBW, sETA, sMsg;
1406 
1407  if ( !BoxDialogSanityCheck() ) {
1408  return;
1409  }
1410 
1411  guiMsg->SetStateString( "visible_msgbox", "1" );
1412  guiMsg->SetStateString( "visible_waitbox", "0" );
1413 
1414  guiMsg->SetStateString( "visible_entry", "0" );
1415  guiMsg->SetStateString( "visible_cdkey", "0" );
1416 
1417  guiMsg->SetStateString( "mid", "Cancel" );
1418  guiMsg->SetStateString( "visible_mid", "1" );
1419  guiMsg->SetStateString( "visible_left", "0" );
1420  guiMsg->SetStateString( "visible_right", "0" );
1421 
1422  guiMsg->SetStateString( "title", title );
1423  guiMsg->SetStateString( "message", "Connecting.." );
1424 
1426  guiActive = guiMsg;
1427  msgRunning = true;
1428 
1429  while ( 1 ) {
1430  while ( msgRunning ) {
1431  common->GUIFrame( true, false );
1432  if ( bgl->completed ) {
1434  guiMsgRestore = NULL;
1435  return;
1436  } else if ( bgl->url.dltotal != dltotal || bgl->url.dlnow != dlnow ) {
1437  dltotal = bgl->url.dltotal;
1438  dlnow = bgl->url.dlnow;
1439  lapsed = Sys_Milliseconds() - startTime;
1440  sNow.BestUnit( "%.2f", dlnow, MEASURE_SIZE );
1441  if ( lapsed > 2000 ) {
1442  sBW.BestUnit( "%.1f", ( 1000.0f * dlnow ) / lapsed, MEASURE_BANDWIDTH );
1443  } else {
1444  sBW = "-- KB/s";
1445  }
1446  if ( dltotal ) {
1447  sTotal.BestUnit( "%.2f", dltotal, MEASURE_SIZE );
1448  if ( lapsed < 2000 ) {
1449  sprintf( sMsg, "%s / %s", sNow.c_str(), sTotal.c_str() );
1450  } else {
1451  sprintf( sETA, "%.0f sec", ( (float)dltotal / (float)dlnow - 1.0f ) * lapsed / 1000 );
1452  sprintf( sMsg, "%s / %s ( %s - %s )", sNow.c_str(), sTotal.c_str(), sBW.c_str(), sETA.c_str() );
1453  }
1454  } else {
1455  if ( lapsed < 2000 ) {
1456  sMsg = sNow;
1457  } else {
1458  sprintf( sMsg, "%s - %s", sNow.c_str(), sBW.c_str() );
1459  }
1460  }
1461  if ( dltotal ) {
1462  guiMsg->SetStateString( "progress", va( "%d", progress_start + dlnow * ( progress_end - progress_start ) / dltotal ) );
1463  } else {
1464  guiMsg->SetStateString( "progress", "0" );
1465  }
1466  guiMsg->SetStateString( "message", sMsg.c_str() );
1467  }
1468  }
1469  // abort was used - tell the downloader and wait till final stop
1470  bgl->url.status = DL_ABORTING;
1471  guiMsg->SetStateString( "title", "Aborting.." );
1472  guiMsg->SetStateString( "visible_mid", "0" );
1473  // continue looping
1475  guiActive = guiMsg;
1476  msgRunning = true;
1477  }
1478 }
1479 
1480 /*
1481 =================
1482 idSessionLocal::StopBox
1483 =================
1484 */
1486  if ( guiActive == guiMsg ) {
1487  HandleMsgCommands( "stop" );
1488  }
1489 }
1490 
1491 /*
1492 =================
1493 idSessionLocal::HandleMsgCommands
1494 =================
1495 */
1496 void idSessionLocal::HandleMsgCommands( const char *menuCommand ) {
1497  assert( guiActive == guiMsg );
1498  // "stop" works even on first frame
1499  if ( idStr::Icmp( menuCommand, "stop" ) == 0 ) {
1500  // force hiding the current dialog
1502  guiMsgRestore = NULL;
1503  msgRunning = false;
1504  msgRetIndex = -1;
1505  }
1506  if ( msgIgnoreButtons ) {
1507  common->DPrintf( "MessageBox HandleMsgCommands 1st frame ignore\n" );
1508  return;
1509  }
1510  if ( idStr::Icmp( menuCommand, "mid" ) == 0 || idStr::Icmp( menuCommand, "left" ) == 0 ) {
1512  guiMsgRestore = NULL;
1513  msgRunning = false;
1514  msgRetIndex = 0;
1515  DispatchCommand( guiActive, msgFireBack[ 0 ].c_str() );
1516  } else if ( idStr::Icmp( menuCommand, "right" ) == 0 ) {
1518  guiMsgRestore = NULL;
1519  msgRunning = false;
1520  msgRetIndex = 1;
1521  DispatchCommand( guiActive, msgFireBack[ 1 ].c_str() );
1522  }
1523 }
1524 
1525 /*
1526 =================
1527 idSessionLocal::HandleNoteCommands
1528 =================
1529 */
1530 #define NOTEDATFILE "C:/notenumber.dat"
1531 
1532 void idSessionLocal::HandleNoteCommands( const char *menuCommand ) {
1533  guiActive = NULL;
1534 
1535  if ( idStr::Icmp( menuCommand, "note" ) == 0 && mapSpawned ) {
1536 
1537  idFile *file = NULL;
1538  for ( int tries = 0; tries < 10; tries++ ) {
1540  if ( file != NULL ) {
1541  break;
1542  }
1543  Sys_Sleep( 500 );
1544  }
1545  int noteNumber = 1000;
1546  if ( file ) {
1547  file->Read( &noteNumber, 4 );
1548  fileSystem->CloseFile( file );
1549  }
1550 
1551  int i;
1552  idStr str, noteNum, shotName, workName, fileName = "viewnotes/";
1553  idStrList fileList;
1554 
1555  const char *severity = NULL;
1556  const char *p = guiTakeNotes->State().GetString( "notefile" );
1557  if ( p == NULL || *p == '\0' ) {
1558  p = cvarSystem->GetCVarString( "ui_name" );
1559  }
1560 
1561  bool extended = guiTakeNotes->State().GetBool( "extended" );
1562  if ( extended ) {
1563  if ( guiTakeNotes->State().GetInt( "severity" ) == 1 ) {
1564  severity = "WishList_Viewnotes/";
1565  } else {
1566  severity = "MustFix_Viewnotes/";
1567  }
1568  fileName += severity;
1569 
1570  const idDecl *mapDecl = declManager->FindType(DECL_ENTITYDEF, mapSpawnData.serverInfo.GetString( "si_map" ), false );
1571  const idDeclEntityDef *mapInfo = static_cast<const idDeclEntityDef *>(mapDecl);
1572 
1573  if ( mapInfo ) {
1574  fileName += mapInfo->dict.GetString( "devname" );
1575  } else {
1576  fileName += mapSpawnData.serverInfo.GetString( "si_map" );
1577  fileName.StripFileExtension();
1578  }
1579 
1580  int count = guiTakeNotes->State().GetInt( "person_numsel" );
1581  if ( count == 0 ) {
1582  fileList.Append( fileName + "/Nobody" );
1583  } else {
1584  for ( i = 0; i < count; i++ ) {
1585  int person = guiTakeNotes->State().GetInt( va( "person_sel_%i", i ) );
1586  workName = fileName + "/";
1587  workName += guiTakeNotes->State().GetString( va( "person_item_%i", person ), "Nobody" );
1588  fileList.Append( workName );
1589  }
1590  }
1591  } else {
1592  fileName += "maps/";
1593  fileName += mapSpawnData.serverInfo.GetString( "si_map" );
1594  fileName.StripFileExtension();
1595  fileList.Append( fileName );
1596  }
1597 
1598  bool bCon = cvarSystem->GetCVarBool( "con_noPrint" );
1599  cvarSystem->SetCVarBool( "con_noPrint", true );
1600  for ( i = 0; i < fileList.Num(); i++ ) {
1601  workName = fileList[i];
1602  workName += "/";
1603  workName += p;
1604  int workNote = noteNumber;
1605  R_ScreenshotFilename( workNote, workName, shotName );
1606 
1607  noteNum = shotName;
1608  noteNum.StripPath();
1609  noteNum.StripFileExtension();
1610 
1611  if ( severity && *severity ) {
1612  workName = severity;
1613  workName += "viewNotes";
1614  }
1615 
1616  sprintf( str, "recordViewNotes \"%s\" \"%s\" \"%s\"\n", workName.c_str(), noteNum.c_str(), guiTakeNotes->State().GetString( "note" ) );
1617 
1620 
1621  UpdateScreen();
1623  }
1624  noteNumber++;
1625 
1626  for ( int tries = 0; tries < 10; tries++ ) {
1627  file = fileSystem->OpenExplicitFileWrite( "p:/viewnotes/notenumber.dat" );
1628  if ( file != NULL ) {
1629  break;
1630  }
1631  Sys_Sleep( 500 );
1632  }
1633  if ( file ) {
1634  file->Write( &noteNumber, 4 );
1635  fileSystem->CloseFile( file );
1636  }
1637 
1638  cmdSystem->BufferCommandText( CMD_EXEC_NOW, "closeViewNotes\n" );
1639  cvarSystem->SetCVarBool( "con_noPrint", bCon );
1640  }
1641 }
1642 
1643 /*
1644 ===============
1645 idSessionLocal::SetCDKeyGuiVars
1646 ===============
1647 */
1649  if ( !guiMainMenu ) {
1650  return;
1651  }
1652  guiMainMenu->SetStateString( "str_d3key_state", common->GetLanguageDict()->GetString( va( "#str_071%d", 86 + cdkey_state ) ) );
1653  guiMainMenu->SetStateString( "str_xpkey_state", common->GetLanguageDict()->GetString( va( "#str_071%d", 86 + xpkey_state ) ) );
1654 }
static bool UnbindBinding(const char *bind)
Definition: KeyInput.cpp:648
void GUIUpdateSelected(void)
Definition: ServerScan.cpp:385
virtual void SetCVarInteger(const char *name, const int value, int flags=0)=0
virtual idFile * OpenFileRead(const char *relativePath, bool allowCopyFiles=true, const char *gamedir=NULL)=0
char xpkey[CDKEY_BUF_LEN]
void HandleRestartMenuCommands(const char *menuCommand)
idStr GetAutoSaveName(const char *mapName) const
Definition: Session.cpp:1208
virtual void Add(int id, const idStr &s)=0
int GetInt(const char *key, const char *defaultString="0") const
Definition: Dict.h:252
idStr & SetFileExtension(const char *extension)
Definition: Str.cpp:743
idDemoFile * readDemo
Definition: Session.h:158
virtual idFileList * ListFiles(const char *relativePath, const char *extension, bool sort=false, bool fullRelativePath=false, const char *gamedir=NULL)=0
assert(prefInfo.fullscreenBtn)
virtual void StateChanged(int time, bool redraw=false)=0
idCVarSystem * cvarSystem
Definition: CVarSystem.cpp:487
void GetSaveGameList(idStrList &fileList, idList< fileTIME_T > &fileTimes)
idSoundWorld * sw
Definition: Session.h:154
virtual void SetCVarFloat(const char *name, const float value, int flags=0)=0
virtual void SetStateString(const char *varName, const char *value)=0
virtual void virtual void virtual const idLangDict * GetLanguageDict(void)=0
void SetNum(int newnum, bool resize=true)
Definition: List.h:289
void ScrubSaveGameFileName(idStr &saveFileName) const
Definition: Session.cpp:1863
idUserInterface * guiMsg
urlDownload_t url
Definition: FileSystem.h:117
virtual int ReadFile(const char *relativePath, void **buffer, ID_TIME_T *timestamp=NULL)=0
int Length(void) const
Definition: Str.h:702
void R_ScreenshotFilename(int &lastNumber, const char *base, idStr &fileName)
virtual const char * MessageBox(msgBoxType_t type, const char *message, const char *title=NULL, bool wait=false, const char *fire_yes=NULL, const char *fire_no=NULL, bool network=false)
const idStrList & GetList(void) const
Definition: FileSystem.h:128
virtual void SetModifiedFlags(int flags)=0
virtual int GetNumMaps()=0
virtual int GetCVarInteger(const char *name) const =0
virtual void PlayShaderDirectly(const char *name, int channel=-1)=0
static idAsyncClient client
Definition: AsyncNetwork.h:168
GLenum GLsizei n
Definition: glext.h:3705
idRenderSystem * renderSystem
bool IsEmpty(void) const
Definition: Str.h:720
int Sys_Milliseconds(void)
void MenuEvent(const sysEvent_t *event)
dlStatus_t status
Definition: FileSystem.h:103
idFileSystem * fileSystem
Definition: FileSystem.cpp:500
virtual idFile * OpenExplicitFileRead(const char *OSPath)=0
idCVar com_machineSpec("com_machineSpec","-1", CVAR_INTEGER|CVAR_ARCHIVE|CVAR_SYSTEM,"hardware classification, -1 = not detected, 0 = low quality, 1 = medium quality, 2 = high quality, 3 = ultra quality")
virtual void ExecuteCommandBuffer(void)=0
virtual void HandleNamedEvent(const char *eventName)=0
virtual void FindMapScreenshot(const char *path, char *buf, int len)=0
const char * Left(int len, idStr &result) const
Definition: Str.h:892
virtual const char * HandleGuiCommands(const char *menuCommand)=0
virtual int IsEAXAvailable(void)=0
virtual void SetCVarString(const char *name, const char *value, int flags=0)=0
virtual void SetKeyBindingNames(void)=0
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
idCmdSystem * cmdSystem
Definition: CmdSystem.cpp:116
Definition: Token.h:71
virtual bool CDKeysAreValid(bool strict)=0
void Sys_Sleep(const int time)
Definition: macosx_sys.mm:67
virtual void ExitMenu()
virtual void SetStateInt(const char *varName, const int value)=0
virtual const idMaterial * FindMaterial(const char *name, bool makeDefault=true)=0
int com_frameTime
Definition: Common.cpp:94
void ReloadImages(bool force) const
Definition: Material.cpp:2723
GLdouble s
Definition: glext.h:2935
GLuint src
Definition: glext.h:5390
void SendVersionCheck(bool fromMenu=false)
int i
Definition: process.py:33
idStrList loadGameList
Definition: KeyInput.h:91
GLuint GLuint num
Definition: glext.h:5390
const char * GetDescription(int index) const
Definition: FileSystem.h:141
void UpdateMPLevelShot(void)
HandleGuiCommand_t guiHandle
virtual const char * HandleEvent(const sysEvent_t *event, int time, bool *updateVisuals=NULL)=0
int Icmp(const char *text) const
Definition: Str.h:667
int BestUnit(const char *format, float value, Measure_t measure)
Definition: Str.cpp:1591
volatile bool completed
Definition: FileSystem.h:118
int GetNumMods(void) const
Definition: FileSystem.h:139
virtual int Num(void)=0
idConsole * console
Definition: Console.cpp:122
cdKeyState_t xpkey_state
idSoundWorld * menuSoundWorld
idStr & StripPath(void)
Definition: Str.cpp:885
virtual void Pause(void)=0
void MoveToNewMap(const char *mapName)
Definition: Session.cpp:1225
idUserInterface * guiTest
virtual void RemoveFile(const char *relativePath)=0
Definition: File.h:50
virtual void SetSelection(int sel)=0
virtual void DeleteStateVar(const char *varName)=0
void ApplyFilter()
Definition: ServerScan.cpp:477
virtual void BufferCommandText(cmdExecution_t exec, const char *text)=0
bool BoxDialogSanityCheck(void)
Definition: Lexer.h:137
void Sort(cmp_t *compare=(cmp_t *)&idListSortCompare< type >)
Definition: List.h:898
GLuint GLuint GLsizei count
Definition: glext.h:2845
Definition: KeyInput.h:80
idListGUI * guiMainMenu_MapList
idStrList modsList
idStr msgFireBack[2]
const char * GetString(const char *key, const char *defaultString="") const
Definition: Dict.h:240
void SetMainMenuGuiVars(void)
idStr & StripFileExtension(void)
Definition: Str.cpp:757
void DispatchCommand(idUserInterface *gui, const char *menuCommand, bool doIngame=true)
#define MAX_STRING_CHARS
Definition: Lib.h:95
void SetSaveGameGuiVars(void)
virtual void GUIFrame(bool execCmd, bool network)=0
virtual void ClearAllSoundEmitters(void)=0
static int NumBinds(const char *binding)
Definition: KeyInput.cpp:668
virtual void SetPlayingSoundWorld(idSoundWorld *soundWorld)=0
idUserInterface * guiActive
idUserInterface * guiTakeNotes
idCommon * common
Definition: Common.cpp:206
virtual void SetCursor(float x, float y)=0
void StartNewGame(const char *mapName, bool devmap=false)
Definition: Session.cpp:1150
bool GetBool(const char *key, const char *defaultString="0") const
Definition: Dict.h:256
Definition: Dict.h:65
#define NULL
Definition: Lib.h:88
virtual const char * GetCVarString(const char *name) const =0
void HandleMsgCommands(const char *menuCommand)
virtual const idDecl * FindType(declType_t type, const char *name, bool makeDefault=true)=0
void SetInteger(const int value)
Definition: CVarSystem.h:148
int evValue2
Definition: sys_public.h:218
virtual void SetCVarBool(const char *name, const bool value, int flags=0)=0
int GetInteger(void) const
Definition: CVarSystem.h:143
virtual int GetSelection(char *s, int size, int sel=0) const =0
idServerScan serverList
Definition: AsyncClient.h:117
virtual int Read(void *buffer, int len)
Definition: File.cpp:179
static void GetNETServers()
const char * GetString(const char *str) const
Definition: LangDict.cpp:148
virtual int GetScreenWidth(void) const =0
void HandleChatMenuCommands(const char *menuCommand)
virtual const char * Activate(bool activate, int time)=0
virtual void DownloadProgressBox(backgroundDownload_t *bgl, const char *title, int progress_start=0, int progress_end=100)
void HandleInGameCommands(const char *menuCommand)
int Argc(void) const
Definition: CmdArgs.h:48
Definition: Session.h:51
const char * Right(int len, idStr &result) const
Definition: Str.h:896
int Find(const char c, int start=0, int end=-1) const
Definition: Str.h:874
virtual void UnPause(void)=0
virtual void FreeFileList(idFileList *fileList)=0
idUsercmdGen * usercmdGen
Definition: UsercmdGen.cpp:419
idStr & RemoveColors(void)
Definition: Str.h:849
virtual int GetScreenHeight(void) const =0
virtual float GetCVarFloat(const char *name) const =0
virtual void Close(void)=0
GLubyte GLubyte GLubyte a
Definition: glext.h:4662
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void SetMainMenuSkin(void)
virtual const idDict & State() const =0
virtual bool IsPaused(void)=0
virtual void StartMenu(bool playIntro=false)
sysEventType_t evType
Definition: sys_public.h:216
msgBoxType_t
Definition: Session.h:50
static bool ExecKeyBinding(int keyNum)
Definition: KeyInput.cpp:726
idDeclManager * declManager
mapSpawnData_t mapSpawnData
GLubyte GLubyte b
Definition: glext.h:4662
idUserInterface * guiIntro
void TokenizeString(const char *text, bool keepAsStrings)
Definition: CmdArgs.cpp:106
idUserInterface * GetActiveMenu()
int Append(const type &obj)
Definition: List.h:646
virtual bool Active(void)=0
virtual void Clear(void)=0
static idCVar gui_configServerRate
virtual idFile * OpenExplicitFileWrite(const char *OSPath)=0
ID_INLINE int idListSaveGameCompare(const fileTIME_T *a, const fileTIME_T *b)
virtual void StopBox(void)
static bool KeyIsBoundTo(int keyNum, const char *binding)
Definition: KeyInput.cpp:686
virtual void GuiFrameEvents()
tuple f
Definition: idal.py:89
idUserInterface * guiMainMenu
int Num(void) const
Definition: List.h:265
virtual void UpdateScreen(bool outOfSequence=true)
Definition: Session.cpp:2471
const char *(* HandleGuiCommand_t)(const char *)
Definition: Session.h:61
void NetScan()
Definition: ServerScan.cpp:254
virtual void SetGUI(idUserInterface *gui, HandleGuiCommand_t handle)
bool LoadGame(const char *saveName)
Definition: Session.cpp:2040
const GLcharARB * name
Definition: glext.h:3629
idSoundSystem * soundSystem
Definition: snd_system.cpp:92
#define NOTEDATFILE
virtual int Write(const void *buffer, int len)
Definition: File.cpp:189
Definition: Str.h:116
void SetSorting(serverSort_t sort)
Definition: ServerScan.cpp:627
const char * Sys_TimeStampToStr(ID_TIME_T timeStamp)
Definition: sys_local.cpp:164
void HandleIntroMenuCommands(const char *menuCommand)
idCVar si_map("si_map","game/mp/d3dm1", CVAR_GAME|CVAR_SERVERINFO|CVAR_ARCHIVE,"map to be played next on server", idCmdSystem::ArgCompletion_MapName)
virtual void SetCDKeyGuiVars(void)
const char * c_str(void) const
Definition: Str.h:487
bool HandleSaveGameMenuCommand(idCmdArgs &args, int &icmd)
virtual bool GetCVarBool(const char *name) const =0
char cdkey[CDKEY_BUF_LEN]
static void SetBinding(int keyNum, const char *binding)
Definition: KeyInput.cpp:415
const char * Argv(int arg) const
Definition: CmdArgs.h:50
virtual void Quit(void)=0
void SetModsMenuGuiVars(void)
virtual bool IsMultiplayer()
Definition: Session.cpp:452
idGame * game
Definition: Game_local.cpp:65
virtual bool IsInitialized(void) const =0
idSession * session
Definition: Session.cpp:48
virtual void InhibitUsercmd(inhibit_t subsystem, bool inhibit)=0
char * va(const char *fmt,...)
Definition: Str.cpp:1568
virtual void CloseFile(idFile *f)=0
ID_TIME_T timeStamp
Definition: Session_local.h:60
virtual void DPrintf(const char *fmt,...) id_attribute((format(printf
virtual const idDict * GetMapDecl(int i)=0
virtual void FreeModList(idModList *modList)=0
GLfloat GLfloat p
Definition: glext.h:4674
const char * GetMod(int index) const
Definition: FileSystem.h:140
cdKeyState_t cdkey_state
idUserInterface * guiMsgRestore
idUserInterface * guiRestartMenu
ID_INLINE T Min(T x, T y)
Definition: Lib.h:159
int ReadToken(idToken *token)
Definition: Lexer.cpp:820
void UnloadMap()
Definition: Session.cpp:1413
virtual void HandleMainMenuCommands(const char *menuCommand, idUserInterface *gui)=0
int sprintf(idStr &string, const char *fmt,...)
Definition: Str.cpp:1528
virtual bool HasD3XP(void)=0
void HandleMainMenuCommands(const char *menuCommand)
bool SaveGame(const char *saveName, bool autosave=false)
Definition: Session.cpp:1894
virtual void TakeScreenshot(int width, int height, const char *fileName, int samples, struct renderView_s *ref)=0
void SetPbMenuGuiVars(void)
int LoadFile(const char *filename, bool OSPath=false)
Definition: Lexer.cpp:1591
idSessionLocal sessLocal
Definition: Session.cpp:47
void Clear(void)
Definition: List.h:184
void HandleNoteCommands(const char *menuCommand)
virtual idModList * ListMods(void)=0