doominterface.cpp (7568B)
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 #include "Precompiled.h" 30 31 #include <stdio.h> 32 33 #include "globaldata.h" 34 #include "doominterface.h" 35 #include "Main.h" 36 #include "m_menu.h" 37 #include "g_game.h" 38 39 extern void I_SetTime( int ); 40 41 bool waitingForWipe; 42 43 static const int dargc = 7; 44 static char* dargv[4][7] = 45 { 46 { "doomlauncher", "-net", "0", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" }, 47 { "doomlauncher", "-net", "1", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" }, 48 { "doomlauncher", "-net", "2", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" }, 49 { "doomlauncher", "-net", "3", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" }, 50 }; 51 52 static int mpArgc[4]; 53 static char mpArgV[4][10][32]; 54 static char* mpArgVPtr[4][10]; 55 56 static bool drawFullScreen = false; 57 58 DoomInterface::DoomInterface() { 59 numplayers = 0; 60 bFinished[0] = bFinished[1] = bFinished[2] = bFinished[3] = false; 61 lastTicRun = 0; 62 } 63 64 DoomInterface::~DoomInterface() { 65 } 66 67 68 void DoomInterface::Startup( int playerscount, bool multiplayer ) 69 { 70 int i; 71 int localdargc = 1; // for the commandline 72 73 numplayers = playerscount; 74 globalNetworking = multiplayer; 75 lastTicRun = 0; 76 77 if (DoomLib::Z_Malloc == NULL) { 78 DoomLib::Z_Malloc = Z_Malloc; 79 } 80 81 // Splitscreen 82 if ( !multiplayer && playerscount > 1 ) { 83 localdargc += 2; // for the '-net' and the console number 84 localdargc += playerscount; 85 } 86 87 if ( multiplayer ) { 88 // Force online games to 1 local player for now. 89 // TODO: We should support local splitscreen and online. 90 numplayers = 1; 91 } 92 93 // Start up DooM Classic 94 for ( i = 0; i < numplayers; ++i) 95 { 96 DoomLib::SetPlayer(i); 97 98 bFinished[i] = false; 99 DoomLib::InitGlobals( NULL ); 100 101 if ( globalNetworking ) { 102 printf( "Starting mulitplayer game, argv = " ); 103 for ( int j = 0; j < mpArgc[0]; ++j ) { 104 printf( " %s", mpArgVPtr[0][j] ); 105 } 106 printf( "\n" ); 107 DoomLib::InitGame(mpArgc[i], mpArgVPtr[i] ); 108 } else { 109 DoomLib::InitGame(localdargc, dargv[i] ); 110 } 111 112 if( DoomLib::skipToLoad ) { 113 G_LoadGame( DoomLib::loadGamePath ); 114 DoomLib::skipToLoad = false; 115 ::g->menuactive = 0; 116 } 117 118 if( DoomLib::skipToNew ) { 119 static int startLevel = 1; 120 G_DeferedInitNew((skill_t)DoomLib::chosenSkill,DoomLib::chosenEpisode+1, startLevel); 121 DoomLib::skipToNew = false; 122 ::g->menuactive = 0; 123 } 124 125 DoomLib::SetPlayer(-1); 126 } 127 } 128 129 bool DoomInterface::Frame( int iTime, idUserCmdMgr * userCmdMgr ) 130 { 131 int i; 132 bool bAllFinished = true; 133 134 if ( !globalNetworking || ( lastTicRun < iTime ) ) { 135 136 drawFullScreen = false; 137 138 DoomLib::SetPlayer( 0 ); 139 DoomLib::PollNetwork(); 140 141 for (i = 0; i < numplayers; ++i) 142 { 143 DoomLib::SetPlayer( i ); 144 145 I_SetTime( iTime ); 146 147 if (bFinished[i] == false) { 148 bAllFinished = false; 149 bFinished[i] = DoomLib::Poll(); 150 } else { 151 152 if (::g->wipedone) { 153 if ( !waitingForWipe ) { 154 const bool didRunTic = DoomLib::Tic( userCmdMgr ); 155 if ( didRunTic == false ) { 156 //printf( "Skipping tic and yielding because not enough time has passed.\n" ); 157 158 // Give lower priority threads a chance to run. 159 Sys_Yield(); 160 } 161 } 162 DoomLib::Frame(); 163 } 164 if (::g->wipe) { 165 DoomLib::Wipe(); 166 // Draw the menus over the wipe. 167 M_Drawer(); 168 } 169 170 if( ::g->gamestate != GS_LEVEL && GetNumPlayers() > 2 ) { 171 drawFullScreen = true; 172 } 173 } 174 175 DoomLib::SetPlayer(-1); 176 } 177 178 DoomLib::SetPlayer( 0 ); 179 DoomLib::SendNetwork(); 180 DoomLib::RunSound(); 181 DoomLib::SetPlayer( -1 ); 182 183 lastTicRun = iTime; 184 } else { 185 printf( "Skipping this frame becase it's not time to run a tic yet.\n" ); 186 } 187 188 return bAllFinished; 189 } 190 191 void I_ShutdownNetwork(); 192 193 void DoomInterface::Shutdown() { 194 int i; 195 196 for ( i=0; i < numplayers; i++ ) { 197 DoomLib::SetPlayer( i ); 198 D_QuitNetGame(); 199 } 200 201 // Shutdown local network state 202 I_ShutdownNetwork(); 203 204 for ( i=0; i < numplayers; i++ ) { 205 DoomLib::SetPlayer( i ); 206 DoomLib::Shutdown(); 207 } 208 209 DoomLib::SetPlayer( -1 ); 210 numplayers = 0; 211 lastTicRun = 0; 212 } 213 214 qboolean G_CheckDemoStatus( void ); 215 216 void DoomInterface::QuitCurrentGame() { 217 for ( int i = 0; i < numplayers; i++ ) { 218 DoomLib::SetPlayer( i ); 219 220 if(::g->netgame) { 221 // Shut down networking 222 D_QuitNetGame(); 223 } 224 225 G_CheckDemoStatus(); 226 227 globalPauseTime = false; 228 ::g->menuactive = false; 229 ::g->usergame = false; 230 ::g->netgame = false; 231 232 lastTicRun = 0; 233 234 //if ( !gameLocal->IsSplitscreen() ) { 235 // Start background demos 236 D_StartTitle(); 237 //} 238 } 239 240 // Shutdown local network state 241 I_ShutdownNetwork(); 242 } 243 244 void DoomInterface::EndDMGame() { 245 246 for ( int i = 0; i < numplayers; i++ ) { 247 DoomLib::SetPlayer( i ); 248 249 if(::g->netgame) { 250 D_QuitNetGame(); 251 } 252 253 G_CheckDemoStatus(); 254 255 globalPauseTime = false; 256 ::g->menuactive = false; 257 ::g->usergame = false; 258 ::g->netgame = false; 259 260 lastTicRun = 0; 261 262 D_StartTitle(); 263 } 264 } 265 266 //static 267 int DoomInterface::CurrentPlayer() { 268 return DoomLib::GetPlayer(); 269 } 270 271 int DoomInterface::GetNumPlayers() const { 272 return numplayers; 273 } 274 275 #ifdef ID_ENABLE_DOOM_CLASSIC_NETWORKING 276 void DoomInterface::SetNetworking( DoomLib::RecvFunc recv, DoomLib::SendFunc send, DoomLib::SendRemoteFunc sendRemote ) { 277 DoomLib::SetNetworking( recv, send, sendRemote ); 278 } 279 #endif 280 281 void DoomInterface::SetMultiplayerPlayers(int localPlayerIndex, int playerCount, int localPlayer, std::vector<std::string> playerAddresses) { 282 283 for(int i = 0; i < 10; i++) { 284 mpArgVPtr[localPlayerIndex][i] = mpArgV[localPlayerIndex][i]; 285 } 286 287 mpArgc[localPlayerIndex] = playerCount+5; 288 289 strcpy(mpArgV[localPlayerIndex][0], "doomlauncher"); 290 strcpy(mpArgV[localPlayerIndex][1], "-dup"); 291 strcpy(mpArgV[localPlayerIndex][2], "1"); 292 strcpy(mpArgV[localPlayerIndex][3], "-net"); 293 294 sprintf(mpArgV[localPlayerIndex][4], "%d", localPlayer); 295 strcpy(mpArgV[localPlayerIndex][5], playerAddresses[localPlayer].c_str()); 296 297 int currentArg = 6; 298 for(int i = 0; i < playerCount; i++) { 299 if(i != localPlayer) { 300 strcpy(mpArgV[localPlayerIndex][currentArg], playerAddresses[i].c_str()); 301 currentArg++; 302 } 303 } 304 } 305