Common_local.h (17449B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition 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 BFG Edition 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 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition 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 BFG Edition 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 static const int MAX_USERCMD_BACKUP = 256; 30 static const int NUM_USERCMD_RELAY = 10; 31 static const int NUM_USERCMD_SEND = 8; 32 33 static const int initialHz = 60; 34 static const int initialBaseTicks = 1000 / initialHz; 35 static const int initialBaseTicksPerSec = initialHz * initialBaseTicks; 36 37 static const int LOAD_TIP_CHANGE_INTERVAL = 12000; 38 static const int LOAD_TIP_COUNT = 26; 39 40 class idGameThread : public idSysThread { 41 public: 42 idGameThread() : 43 gameTime(), 44 drawTime(), 45 threadTime(), 46 threadGameTime(), 47 threadRenderTime(), 48 userCmdMgr( NULL ), 49 ret(), 50 numGameFrames(), 51 isClient() 52 {} 53 54 // the gameReturn_t is from the previous frame, the 55 // new frame will be running in parallel on exit 56 gameReturn_t RunGameAndDraw( int numGameFrames, idUserCmdMgr & userCmdMgr_, bool isClient_, int startGameFrame ); 57 58 // Accessors to the stored frame/thread time information 59 void SetThreadTotalTime( const int inTime ) { threadTime = inTime; } 60 int GetThreadTotalTime() const { return threadTime; } 61 62 void SetThreadGameTime( const int time ) { threadGameTime = time; } 63 int GetThreadGameTime() const { return threadGameTime; } 64 65 void SetThreadRenderTime( const int time ) { threadRenderTime = time; } 66 int GetThreadRenderTime() const { return threadRenderTime; } 67 68 private: 69 virtual int Run(); 70 71 int gameTime; 72 int drawTime; 73 int threadTime; // total time : game time + foreground render time 74 int threadGameTime; // game time only 75 int threadRenderTime; // render fg time only 76 idUserCmdMgr * userCmdMgr; 77 gameReturn_t ret; 78 int numGameFrames; 79 bool isClient; 80 }; 81 82 enum errorParm_t { 83 ERP_NONE, 84 ERP_FATAL, // exit the entire game with a popup window 85 ERP_DROP, // print to console and disconnect from game 86 ERP_DISCONNECT // don't kill server 87 }; 88 89 enum gameLaunch_t { 90 LAUNCH_TITLE_DOOM = 0, 91 LAUNCH_TITLE_DOOM2, 92 }; 93 94 struct netTimes_t { 95 int localTime; 96 int serverTime; 97 }; 98 99 struct frameTiming_t { 100 uint64 startSyncTime; 101 uint64 finishSyncTime; 102 uint64 startGameTime; 103 uint64 finishGameTime; 104 uint64 finishDrawTime; 105 uint64 startRenderTime; 106 uint64 finishRenderTime; 107 }; 108 109 #define MAX_PRINT_MSG_SIZE 4096 110 #define MAX_WARNING_LIST 256 111 112 #define SAVEGAME_CHECKPOINT_FILENAME "gamedata.save" 113 #define SAVEGAME_DESCRIPTION_FILENAME "gamedata.txt" 114 #define SAVEGAME_STRINGS_FILENAME "gamedata.strings" 115 116 class idCommonLocal : public idCommon { 117 public: 118 idCommonLocal(); 119 120 virtual void Init( int argc, const char * const * argv, const char *cmdline ); 121 virtual void Shutdown(); 122 virtual void CreateMainMenu(); 123 virtual void Quit(); 124 virtual bool IsInitialized() const; 125 virtual void Frame(); 126 virtual void UpdateScreen( bool captureToImage ); 127 virtual void UpdateLevelLoadPacifier(); 128 virtual void StartupVariable( const char * match ); 129 virtual void WriteConfigToFile( const char *filename ); 130 virtual void BeginRedirect( char *buffer, int buffersize, void (*flush)( const char * ) ); 131 virtual void EndRedirect(); 132 virtual void SetRefreshOnPrint( bool set ); 133 virtual void Printf( VERIFY_FORMAT_STRING const char *fmt, ... ); 134 virtual void VPrintf( const char *fmt, va_list arg ); 135 virtual void DPrintf( VERIFY_FORMAT_STRING const char *fmt, ... ); 136 virtual void Warning( VERIFY_FORMAT_STRING const char *fmt, ... ); 137 virtual void DWarning( VERIFY_FORMAT_STRING const char *fmt, ...); 138 virtual void PrintWarnings(); 139 virtual void ClearWarnings( const char *reason ); 140 virtual void Error( VERIFY_FORMAT_STRING const char *fmt, ... ); 141 virtual void FatalError( VERIFY_FORMAT_STRING const char *fmt, ... ); 142 virtual bool IsShuttingDown() const { return com_shuttingDown; } 143 144 virtual const char * KeysFromBinding( const char *bind ); 145 virtual const char * BindingFromKey( const char *key ); 146 147 virtual bool IsMultiplayer(); 148 virtual bool IsServer(); 149 virtual bool IsClient(); 150 151 virtual bool GetConsoleUsed() { return consoleUsed; } 152 153 virtual int GetSnapRate(); 154 155 virtual void NetReceiveReliable( int peer, int type, idBitMsg & msg ); 156 virtual void NetReceiveSnapshot( class idSnapShot & ss ); 157 virtual void NetReceiveUsercmds( int peer, idBitMsg & msg ); 158 void NetReadUsercmds( int clientNum, idBitMsg & msg ); 159 160 virtual bool ProcessEvent( const sysEvent_t *event ); 161 162 virtual bool LoadGame( const char * saveName ); 163 virtual bool SaveGame( const char * saveName ); 164 165 virtual int ButtonState( int key ); 166 virtual int KeyState( int key ); 167 168 virtual idDemoFile * ReadDemo() { return readDemo; } 169 virtual idDemoFile * WriteDemo() { return writeDemo; } 170 171 virtual idGame * Game() { return game; } 172 virtual idRenderWorld * RW() { return renderWorld; } 173 virtual idSoundWorld * SW() { return soundWorld; } 174 virtual idSoundWorld * MenuSW() { return menuSoundWorld; } 175 virtual idSession * Session() { return session; } 176 virtual idCommonDialog & Dialog() { return commonDialog; } 177 178 virtual void OnSaveCompleted( idSaveLoadParms & parms ); 179 virtual void OnLoadCompleted( idSaveLoadParms & parms ); 180 virtual void OnLoadFilesCompleted( idSaveLoadParms & parms ); 181 virtual void OnEnumerationCompleted( idSaveLoadParms & parms ); 182 virtual void OnDeleteCompleted( idSaveLoadParms & parms ); 183 virtual void TriggerScreenWipe( const char * _wipeMaterial, bool hold ); 184 185 virtual void OnStartHosting( idMatchParameters & parms ); 186 187 virtual int GetGameFrame() { return gameFrame; } 188 189 virtual void LaunchExternalTitle( int titleIndex, 190 int device, 191 const lobbyConnectInfo_t * const connectInfo ); // For handling invitations. NULL if no invitation used. 192 193 virtual void InitializeMPMapsModes(); 194 virtual const idStrList & GetModeList() const { return mpGameModes; } 195 virtual const idStrList & GetModeDisplayList() const { return mpDisplayGameModes; } 196 virtual const idList<mpMap_t> & GetMapList() const { return mpGameMaps; } 197 198 virtual void ResetPlayerInput( int playerIndex ); 199 200 virtual bool JapaneseCensorship() const; 201 202 virtual void QueueShowShell() { showShellRequested = true; } 203 204 virtual currentGame_t GetCurrentGame() const { return currentGame; } 205 virtual void SwitchToGame( currentGame_t newGame ); 206 207 public: 208 void Draw(); // called by gameThread 209 210 int GetGameThreadTotalTime() const { return gameThread.GetThreadTotalTime(); } 211 int GetGameThreadGameTime() const { return gameThread.GetThreadGameTime(); } 212 int GetGameThreadRenderTime() const { return gameThread.GetThreadRenderTime(); } 213 int GetRendererBackEndMicroseconds() const { return time_backend; } 214 int GetRendererShadowsMicroseconds() const { return time_shadows; } 215 int GetRendererIdleMicroseconds() const { return mainFrameTiming.startRenderTime - mainFrameTiming.finishSyncTime; } 216 int GetRendererGPUMicroseconds() const { return time_gpu; } 217 218 frameTiming_t frameTiming; 219 frameTiming_t mainFrameTiming; 220 221 public: // These are public because they are called directly by static functions in this file 222 223 const char * GetCurrentMapName() { return currentMapName.c_str(); } 224 225 // loads a map and starts a new game on it 226 void StartNewGame( const char * mapName, bool devmap, int gameMode ); 227 void LeaveGame(); 228 229 void DemoShot( const char *name ); 230 void StartRecordingRenderDemo( const char *name ); 231 void StopRecordingRenderDemo(); 232 void StartPlayingRenderDemo( idStr name ); 233 void StopPlayingRenderDemo(); 234 void CompressDemoFile( const char *scheme, const char *name ); 235 void TimeRenderDemo( const char *name, bool twice = false, bool quit = false ); 236 void AVIRenderDemo( const char *name ); 237 void AVIGame( const char *name ); 238 239 // localization 240 void InitLanguageDict(); 241 void LocalizeGui( const char *fileName, idLangDict &langDict ); 242 void LocalizeMapData( const char *fileName, idLangDict &langDict ); 243 void LocalizeSpecificMapData( const char *fileName, idLangDict &langDict, const idLangDict &replaceArgs ); 244 245 idUserCmdMgr & GetUCmdMgr() { return userCmdMgr; } 246 247 private: 248 bool com_fullyInitialized; 249 bool com_refreshOnPrint; // update the screen every print for dmap 250 errorParm_t com_errorEntered; 251 bool com_shuttingDown; 252 bool com_isJapaneseSKU; 253 254 idFile * logFile; 255 256 char errorMessage[MAX_PRINT_MSG_SIZE]; 257 258 char * rd_buffer; 259 int rd_buffersize; 260 void (*rd_flush)( const char *buffer ); 261 262 idStr warningCaption; 263 idStrList warningList; 264 idStrList errorList; 265 266 int gameDLL; 267 268 idCommonDialog commonDialog; 269 270 idFile_SaveGame saveFile; 271 idFile_SaveGame stringsFile; 272 idFile_SaveGamePipelined *pipelineFile; 273 274 // The main render world and sound world 275 idRenderWorld * renderWorld; 276 idSoundWorld * soundWorld; 277 278 // The renderer and sound system will write changes to writeDemo. 279 // Demos can be recorded and played at the same time when splicing. 280 idDemoFile * readDemo; 281 idDemoFile * writeDemo; 282 283 bool menuActive; 284 idSoundWorld * menuSoundWorld; // so the game soundWorld can be muted 285 286 bool insideExecuteMapChange; // Enable Pacifier Updates 287 288 // This is set if the player enables the console, which disables achievements 289 bool consoleUsed; 290 291 // This additional information is required for ExecuteMapChange for SP games ONLY 292 // This data is cleared after ExecuteMapChange 293 struct mapSpawnData_t { 294 idFile_SaveGame * savegameFile; // Used for loading a save game 295 idFile_SaveGame * stringTableFile; // String table read from save game loaded 296 idFile_SaveGamePipelined *pipelineFile; 297 int savegameVersion; // Version of the save game we're loading 298 idDict persistentPlayerInfo; // Used for transitioning from map to map 299 }; 300 mapSpawnData_t mapSpawnData; 301 idStr currentMapName; // for checking reload on same level 302 bool mapSpawned; // cleared on Stop() 303 304 bool insideUpdateScreen; // true while inside ::UpdateScreen() 305 306 idUserCmdMgr userCmdMgr; 307 308 int nextUsercmdSendTime; // Next time to send usercmds 309 int nextSnapshotSendTime; // Next time to send a snapshot 310 311 idSnapShot lastSnapShot; // last snapshot we received from the server 312 struct reliableMsg_t { 313 int client; 314 int type; 315 int dataSize; 316 byte * data; 317 }; 318 idList<reliableMsg_t> reliableQueue; 319 320 321 // Snapshot interpolation 322 idSnapShot oldss; // last local snapshot 323 // (ie on server this is the last "master" snapshot we created) 324 // (on clients this is the last received snapshot) 325 // used for comparisons with the new snapshot for com_drawSnapshot 326 327 // This is ultimately controlled by net_maxBufferedSnapshots by running double speed, but this is the hard max before seeing visual popping 328 static const int RECEIVE_SNAPSHOT_BUFFER_SIZE = 16; 329 330 int readSnapshotIndex; 331 int writeSnapshotIndex; 332 idArray<idSnapShot,RECEIVE_SNAPSHOT_BUFFER_SIZE> receivedSnaps; 333 334 float optimalPCTBuffer; 335 float optimalTimeBuffered; 336 float optimalTimeBufferedWindow; 337 338 uint64 snapRate; 339 uint64 actualRate; 340 341 uint64 snapTime; // time we got the most recent snapshot 342 uint64 snapTimeDelta; // time interval that current ss was sent in 343 344 uint64 snapTimeWrite; 345 uint64 snapCurrentTime; // realtime playback time 346 netTimes_t snapCurrent; // current snapshot 347 netTimes_t snapPrevious; // previous snapshot 348 float snapCurrentResidual; 349 350 float snapTimeBuffered; 351 float effectiveSnapRate; 352 int totalBufferedTime; 353 int totalRecvTime; 354 355 356 357 int clientPrediction; 358 359 int gameFrame; // Frame number of the local game 360 double gameTimeResidual; // left over msec from the last game frame 361 bool syncNextGameFrame; 362 363 bool aviCaptureMode; // if true, screenshots will be taken and sound captured 364 idStr aviDemoShortName; // 365 int aviDemoFrameCount; 366 367 enum timeDemo_t { 368 TD_NO, 369 TD_YES, 370 TD_YES_THEN_QUIT 371 }; 372 timeDemo_t timeDemo; 373 int timeDemoStartTime; 374 int numDemoFrames; // for timeDemo and demoShot 375 int demoTimeOffset; 376 renderView_t currentDemoRenderView; 377 378 idStrList mpGameModes; 379 idStrList mpDisplayGameModes; 380 idList<mpMap_t> mpGameMaps; 381 382 idSWF * loadGUI; 383 int nextLoadTip; 384 bool isHellMap; 385 bool defaultLoadscreen; 386 idStaticList<int, LOAD_TIP_COUNT> loadTipList; 387 388 const idMaterial * splashScreen; 389 390 const idMaterial * whiteMaterial; 391 392 const idMaterial * wipeMaterial; 393 int wipeStartTime; 394 int wipeStopTime; 395 bool wipeHold; 396 bool wipeForced; // used for the PS3 to start an early wipe while we are accessing saved game data 397 398 idGameThread gameThread; // the game and draw code can be run in parallel 399 400 // com_speeds times 401 int count_numGameFrames; // total number of game frames that were run 402 int time_gameFrame; // game logic time 403 int time_maxGameFrame; // maximum single frame game logic time 404 int time_gameDraw; // game present time 405 uint64 time_frontend; // renderer frontend time 406 uint64 time_backend; // renderer backend time 407 uint64 time_shadows; // renderer backend waiting for shadow volumes to be created 408 uint64 time_gpu; // total gpu time, at least for PC 409 410 // Used during loading screens 411 int lastPacifierSessionTime; 412 int lastPacifierGuiTime; 413 bool lastPacifierDialogState; 414 415 bool showShellRequested; 416 417 currentGame_t currentGame; 418 currentGame_t idealCurrentGame; // Defer game switching so that bad things don't happen in the middle of the frame. 419 const idMaterial * doomClassicMaterial; 420 421 static const int DOOMCLASSIC_RENDERWIDTH = 320 * 3; 422 static const int DOOMCLASSIC_RENDERHEIGHT = 200 * 3; 423 static const int DOOMCLASSIC_BYTES_PER_PIXEL = 4; 424 static const int DOOMCLASSIC_IMAGE_SIZE_IN_BYTES = DOOMCLASSIC_RENDERWIDTH * DOOMCLASSIC_RENDERHEIGHT * DOOMCLASSIC_BYTES_PER_PIXEL; 425 426 idArray< byte, DOOMCLASSIC_IMAGE_SIZE_IN_BYTES > doomClassicImageData; 427 428 private: 429 void InitCommands(); 430 void InitSIMD(); 431 void AddStartupCommands(); 432 void ParseCommandLine( int argc, const char * const * argv ); 433 bool SafeMode(); 434 void CloseLogFile(); 435 void WriteConfiguration(); 436 void DumpWarnings(); 437 void LoadGameDLL(); 438 void UnloadGameDLL(); 439 void CleanupShell(); 440 void RenderBink( const char * path ); 441 void RenderSplash(); 442 void FilterLangList( idStrList* list, idStr lang ); 443 void CheckStartupStorageRequirements(); 444 445 void ExitMenu(); 446 bool MenuEvent( const sysEvent_t * event ); 447 448 void StartMenu( bool playIntro = false ); 449 void GuiFrameEvents(); 450 451 void BeginAVICapture( const char *name ); 452 void EndAVICapture(); 453 454 void AdvanceRenderDemo( bool singleFrameOnly ); 455 456 void ProcessGameReturn( const gameReturn_t & ret ); 457 458 void RunNetworkSnapshotFrame(); 459 void ExecuteReliableMessages(); 460 461 462 // Snapshot interpolation 463 void ProcessSnapshot( idSnapShot & ss ); 464 int CalcSnapTimeBuffered( int & totalBufferedTime, int & totalRecvTime ); 465 void ProcessNextSnapshot(); 466 void InterpolateSnapshot( netTimes_t & prev, netTimes_t & next, float fraction, bool predict ); 467 void ResetNetworkingState(); 468 469 int NetworkFrame(); 470 void SendSnapshots(); 471 void SendUsercmds( int localClientNum ); 472 473 void LoadLoadingGui(const char *mapName, bool & hellMap ); 474 475 // Meant to be used like: 476 // while ( waiting ) { BusyWait(); } 477 void BusyWait(); 478 bool WaitForSessionState( idSession::sessionState_t desiredState ); 479 480 void ExecuteMapChange(); 481 void UnloadMap(); 482 483 void Stop( bool resetSession = true ); 484 485 // called by Draw when the scene to scene wipe is still running 486 void DrawWipeModel(); 487 void StartWipe( const char *materialName, bool hold = false); 488 void CompleteWipe(); 489 void ClearWipe(); 490 491 void MoveToNewMap( const char * mapName, bool devmap ); 492 493 void PlayIntroGui(); 494 495 void ScrubSaveGameFileName( idStr &saveFileName ) const; 496 497 // Doom classic support 498 void RunDoomClassicFrame(); 499 void RenderDoomClassic(); 500 bool IsPlayingDoomClassic() const { return GetCurrentGame() != DOOM3_BFG; } 501 void PerformGameSwitch(); 502 }; 503 504 extern idCommonLocal commonLocal;