/*
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code. If not, see .
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.
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.
===========================================================================
*/
#include "Precompiled.h"
#include
#include "globaldata.h"
#include "doominterface.h"
#include "Main.h"
#include "m_menu.h"
#include "g_game.h"
extern void I_SetTime( int );
bool waitingForWipe;
static const int dargc = 7;
static const char* dargv[4][7] =
{
{ "doomlauncher", "-net", "0", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" },
{ "doomlauncher", "-net", "1", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" },
{ "doomlauncher", "-net", "2", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" },
{ "doomlauncher", "-net", "3", "127.0.0.1", "127.0.0.1", "127.0.0.1", "127.0.0.1" },
};
static int mpArgc[4];
static char mpArgV[4][10][32];
static char* mpArgVPtr[4][10];
static bool drawFullScreen = false;
DoomInterface::DoomInterface()
{
numplayers = 0;
bFinished[0] = bFinished[1] = bFinished[2] = bFinished[3] = false;
lastTicRun = 0;
}
DoomInterface::~DoomInterface()
{
}
void DoomInterface::Startup( int playerscount, bool multiplayer )
{
int i;
int localdargc = 1; // for the commandline
numplayers = playerscount;
globalNetworking = multiplayer;
lastTicRun = 0;
if( DoomLib::Z_Malloc == NULL )
{
DoomLib::Z_Malloc = Z_Malloc;
}
// Splitscreen
if( !multiplayer && playerscount > 1 )
{
localdargc += 2; // for the '-net' and the console number
localdargc += playerscount;
}
if( multiplayer )
{
// Force online games to 1 local player for now.
// TODO: We should support local splitscreen and online.
numplayers = 1;
}
// Start up DooM Classic
for( i = 0; i < numplayers; ++i )
{
DoomLib::SetPlayer( i );
bFinished[i] = false;
DoomLib::InitGlobals( NULL );
if( globalNetworking )
{
printf( "Starting mulitplayer game, argv = " );
for( int j = 0; j < mpArgc[0]; ++j )
{
printf( " %s", mpArgVPtr[0][j] );
}
printf( "\n" );
DoomLib::InitGame( mpArgc[i], mpArgVPtr[i] );
}
else
{
DoomLib::InitGame( localdargc, ( char** )dargv[i] );
}
if( DoomLib::skipToLoad )
{
G_LoadGame( DoomLib::loadGamePath );
DoomLib::skipToLoad = false;
::g->menuactive = 0;
}
if( DoomLib::skipToNew )
{
static int startLevel = 1;
G_DeferedInitNew( ( skill_t )DoomLib::chosenSkill, DoomLib::chosenEpisode + 1, startLevel );
DoomLib::skipToNew = false;
::g->menuactive = 0;
}
DoomLib::SetPlayer( -1 );
}
}
bool DoomInterface::Frame( int iTime, idUserCmdMgr* userCmdMgr )
{
int i;
bool bAllFinished = true;
if( !globalNetworking || ( lastTicRun < iTime ) )
{
drawFullScreen = false;
DoomLib::SetPlayer( 0 );
DoomLib::PollNetwork();
for( i = 0; i < numplayers; ++i )
{
DoomLib::SetPlayer( i );
I_SetTime( iTime );
if( bFinished[i] == false )
{
bAllFinished = false;
bFinished[i] = DoomLib::Poll();
}
else
{
if( ::g->wipedone )
{
if( !waitingForWipe )
{
const bool didRunTic = DoomLib::Tic( userCmdMgr );
if( didRunTic == false )
{
//printf( "Skipping tic and yielding because not enough time has passed.\n" );
// Give lower priority threads a chance to run.
Sys_Yield();
}
}
DoomLib::Frame();
}
if( ::g->wipe )
{
DoomLib::Wipe();
// Draw the menus over the wipe.
M_Drawer();
}
if( ::g->gamestate != GS_LEVEL && GetNumPlayers() > 2 )
{
drawFullScreen = true;
}
}
DoomLib::SetPlayer( -1 );
}
DoomLib::SetPlayer( 0 );
DoomLib::SendNetwork();
DoomLib::RunSound();
DoomLib::SetPlayer( -1 );
lastTicRun = iTime;
}
else
{
printf( "Skipping this frame becase it's not time to run a tic yet.\n" );
}
return bAllFinished;
}
void I_ShutdownNetwork();
void DoomInterface::Shutdown()
{
int i;
for( i = 0; i < numplayers; i++ )
{
DoomLib::SetPlayer( i );
D_QuitNetGame();
}
// Shutdown local network state
I_ShutdownNetwork();
for( i = 0; i < numplayers; i++ )
{
DoomLib::SetPlayer( i );
DoomLib::Shutdown();
}
DoomLib::SetPlayer( -1 );
numplayers = 0;
lastTicRun = 0;
}
qboolean G_CheckDemoStatus();
void DoomInterface::QuitCurrentGame()
{
for( int i = 0; i < numplayers; i++ )
{
DoomLib::SetPlayer( i );
if( ::g->netgame )
{
// Shut down networking
D_QuitNetGame();
}
G_CheckDemoStatus();
globalPauseTime = false;
::g->menuactive = false;
::g->usergame = false;
::g->netgame = false;
lastTicRun = 0;
//if ( !gameLocal->IsSplitscreen() ) {
// Start background demos
D_StartTitle();
//}
}
// Shutdown local network state
I_ShutdownNetwork();
}
void DoomInterface::EndDMGame()
{
for( int i = 0; i < numplayers; i++ )
{
DoomLib::SetPlayer( i );
if( ::g->netgame )
{
D_QuitNetGame();
}
G_CheckDemoStatus();
globalPauseTime = false;
::g->menuactive = false;
::g->usergame = false;
::g->netgame = false;
lastTicRun = 0;
D_StartTitle();
}
}
//static
int DoomInterface::CurrentPlayer()
{
return DoomLib::GetPlayer();
}
int DoomInterface::GetNumPlayers() const
{
return numplayers;
}
#ifdef ID_ENABLE_DOOM_CLASSIC_NETWORKING
void DoomInterface::SetNetworking( DoomLib::RecvFunc recv, DoomLib::SendFunc send, DoomLib::SendRemoteFunc sendRemote )
{
DoomLib::SetNetworking( recv, send, sendRemote );
}
#endif
void DoomInterface::SetMultiplayerPlayers( int localPlayerIndex, int playerCount, int localPlayer, std::vector playerAddresses )
{
for( int i = 0; i < 10; i++ )
{
mpArgVPtr[localPlayerIndex][i] = mpArgV[localPlayerIndex][i];
}
mpArgc[localPlayerIndex] = playerCount + 5;
strcpy( mpArgV[localPlayerIndex][0], "doomlauncher" );
strcpy( mpArgV[localPlayerIndex][1], "-dup" );
strcpy( mpArgV[localPlayerIndex][2], "1" );
strcpy( mpArgV[localPlayerIndex][3], "-net" );
idStr::snPrintf( mpArgV[localPlayerIndex][4], sizeof( mpArgV[localPlayerIndex][4] ), "%d", localPlayer );
strcpy( mpArgV[localPlayerIndex][5], playerAddresses[localPlayer].c_str() );
int currentArg = 6;
for( int i = 0; i < playerCount; i++ )
{
if( i != localPlayer )
{
strcpy( mpArgV[localPlayerIndex][currentArg], playerAddresses[i].c_str() );
currentArg++;
}
}
}