DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

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