Example #1
0
/*
================
idCommonLocal::ProcessGameReturn
================
*/
void idCommonLocal::ProcessGameReturn( const gameReturn_t & ret ) {
	// set joystick rumble
	if ( in_useJoystick.GetBool() && in_joystickRumble.GetBool() && !game->Shell_IsActive() && session->GetSignInManager().GetMasterInputDevice() >= 0 ) {
		Sys_SetRumble( session->GetSignInManager().GetMasterInputDevice(), ret.vibrationLow, ret.vibrationHigh );		// Only set the rumble on the active controller
	} else {
		for ( int i = 0; i < MAX_INPUT_DEVICES; i++ ) {
			Sys_SetRumble( i, 0, 0 );
		}
	}

	syncNextGameFrame = ret.syncNextGameFrame;

	if ( ret.sessionCommand[0] ) {
		idCmdArgs args;

		args.TokenizeString( ret.sessionCommand, false );

		if ( !idStr::Icmp( args.Argv(0), "map" ) ) {
			MoveToNewMap( args.Argv( 1 ), false );
		} else if ( !idStr::Icmp( args.Argv(0), "devmap" ) ) {
			MoveToNewMap( args.Argv( 1 ), true );
		} else if ( !idStr::Icmp( args.Argv(0), "died" ) ) {
			if ( !IsMultiplayer() ) {
				game->Shell_Show( true );
			}
		} else if ( !idStr::Icmp( args.Argv(0), "disconnect" ) ) {
			cmdSystem->BufferCommandText( CMD_EXEC_INSERT, "stoprecording ; disconnect" );
		} else if ( !idStr::Icmp( args.Argv(0), "endOfDemo" ) ) {
			cmdSystem->BufferCommandText( CMD_EXEC_NOW, "endOfDemo" );
		}
	}
}
Example #2
0
bool NumPlayersSelection(
	GameMode mode, GraphicsDevice *graphics, EventHandlers *handlers)
{
	MenuSystem ms;
	MenuSystemInit(
		&ms, handlers, graphics,
		Vec2iZero(),
		graphics->cachedConfig.Res);
	ms.allowAborts = true;
	ms.root = ms.current = MenuCreateNormal(
		"",
		"Select number of players",
		MENU_TYPE_NORMAL,
		0);
	for (int i = 0; i < MAX_LOCAL_PLAYERS; i++)
	{
		char buf[2];
		if (IsMultiplayer(mode) && i == 0)
		{
			// At least two players for dogfights
			continue;
		}
		sprintf(buf, "%d", i + 1);
		MenuAddSubmenu(ms.current, MenuCreateReturn(buf, i + 1));
	}
	MenuAddExitType(&ms, MENU_TYPE_RETURN);

	MenuLoop(&ms);
	const bool ok = !ms.hasAbort;
	if (ok)
	{
		const int numPlayers = ms.current->u.returnCode;
		for (int i = 0; i < (int)gPlayerDatas.size; i++)
		{
			const PlayerData *p = CArrayGet(&gPlayerDatas, i);
			CASSERT(!p->IsLocal, "unexpected local player");
		}
		if (NetClientIsConnected(&gNetClient))
		{
			// Tell the server that we want to add new players
			NetMsgNewPlayers np;
			np.ClientId = gNetClient.ClientId;
			np.NumPlayers = numPlayers;
			NetClientSendMsg(&gNetClient, MSG_NEW_PLAYERS, &np);
		}
		else
		{
			// We are the server, just add the players
			for (int i = 0; i < numPlayers; i++)
			{
				PlayerData *p = PlayerDataAdd(&gPlayerDatas);
				PlayerDataSetLocalDefaults(p, i);
				p->inputDevice = INPUT_DEVICE_UNSET;
			}
		}
	}
	MenuSystemTerminate(&ms);
	return ok;
}
Example #3
0
edict_t *CHalfLifeMultiplay::GetPlayerSpawnSpot( CBasePlayer *pPlayer )
{
	edict_t *pentSpawnSpot = CGameRules::GetPlayerSpawnSpot( pPlayer );	
	if ( IsMultiplayer() && pentSpawnSpot->v.target )
	{
		FireTargets( STRING(pentSpawnSpot->v.target), pPlayer, pPlayer, USE_TOGGLE, 0 );
	}

	return pentSpawnSpot;
}
Example #4
0
void CGameLobbyManager::DoPendingDeleteSession(CGameLobby *pLobby)
{
	CryLog("CGameLobbyManager::DoPendingDeleteSession() pLobby:%p", pLobby);

	if(pLobby == m_primaryLobby)
	{
		if(m_nextLobby)
		{
			CRY_ASSERT(m_primaryLobby && m_nextLobby);

			SAFE_DELETE(m_primaryLobby);
			m_primaryLobby = m_nextLobby;
			m_nextLobby = NULL;

			m_primaryLobby->SwitchToPrimaryLobby();

			SetPrivateGame(m_primaryLobby, m_primaryLobby->IsPrivateGame());

			CryLog("CGameLobbyManager::DoPendingDeleteSession - Moved to next session");
		}
		else
		{
			CryLog("CGameLobbyManager::DoPendingDeleteSession - No sessions left");
#ifdef USE_C2_FRONTEND
			CFlashFrontEnd *pFlashMenu = g_pGame->GetFlashMenu();
			if (pFlashMenu)
			{
				// Have to go all the way back to main then forward to play_online because the stack may
				// not include play_online (destroyed when we do a level rotation)
				if (IsMultiplayer() && pFlashMenu->IsScreenInStack("game_lobby"))
				{
					if (CMPMenuHub *pMPMenu = CMPMenuHub::GetMPMenuHub())
					{
						pMPMenu->GoToCurrentLobbyServiceScreen(); // go to correct lobby service screen - play_online or play_lan
					}
				}
			}
#endif //#ifdef USE_C2_FRONTEND
			CSquadManager *pSquadManager = g_pGame->GetSquadManager();
			if (pSquadManager)
			{
				pSquadManager->GameSessionIdChanged(CSquadManager::eGSC_LeftSession, CrySessionInvalidID);
			}

			SetPrivateGame(NULL, false);
		}
	}
	else if(pLobby == m_nextLobby)
	{
		CryLog("CGameLobbyManager::DoPendingDeleteSession - Next Lobby deleted");
		SAFE_DELETE(m_nextLobby);
	}

	m_bMergingIsComplete = false;
}
//=========================================================
// CALLED THROUGH the newly-touched weapon's instance. The existing player weapon is pOriginal
//=========================================================
int CSatchel::AddDuplicate(CBasePlayerItem *pOriginal)
{
	CSatchel *pSatchel;

	if (IsMultiplayer())
	{
		pSatchel = (CSatchel *)pOriginal;
		if (pSatchel->m_chargeReady != 0)return FALSE;
	}
	return CBasePlayerWeapon::AddDuplicate(pOriginal);
}
void CRpg::Spawn()
{
	Precache();
	m_iId = WEAPON_RPG;

	SET_MODEL(ENT(pev), "models/w_rpg.mdl");
	m_iOverloadLevel = TRUE;//turn on LTD

	if (IsMultiplayer())m_iDefaultAmmo = RPG_DEFAULT_GIVE * 2;
	else	m_iDefaultAmmo = RPG_DEFAULT_GIVE;
	FallInit();// get ready to fall down.
}
/*
===============
idSessionLocal::SetMainMenuGuiVars
===============
*/
void idSessionLocal::SetMainMenuGuiVars(void)
{

	guiMainMenu->SetStateString("serverlist_sel_0", "-1");
	guiMainMenu->SetStateString("serverlist_selid_0", "-1");

	guiMainMenu->SetStateInt("com_machineSpec", com_machineSpec.GetInteger());

	// "inetGame" will hold a hand-typed inet address, which is not archived to a cvar
	guiMainMenu->SetStateString("inetGame", "");

	// key bind names
	guiMainMenu->SetKeyBindingNames();

	// flag for in-game menu
	if (mapSpawned) {
		guiMainMenu->SetStateString("inGame", IsMultiplayer() ? "2" : "1");
	} else {
		guiMainMenu->SetStateString("inGame", "0");
	}

	SetCDKeyGuiVars();
#ifdef ID_DEMO_BUILD
	guiMainMenu->SetStateString("nightmare", "0");
#else
	guiMainMenu->SetStateString("nightmare", cvarSystem->GetCVarBool("g_nightmare") ? "1" : "0");
#endif
	guiMainMenu->SetStateString("browser_levelshot", "guis/assets/splash/pdtempa");

	SetMainMenuSkin();
	// Mods Menu
	SetModsMenuGuiVars();

	guiMsg->SetStateString("visible_hasxp", fileSystem->HasD3XP() ? "1" : "0");

#if defined( __linux__ )
	guiMainMenu->SetStateString("driver_prompt", "1");
#else
	guiMainMenu->SetStateString("driver_prompt", "0");
#endif

	SetPbMenuGuiVars();
}
Example #8
0
void CTriggerHurt :: Touch ( CBaseEntity *pOther )
{
	float fldmg;

	if ( !pOther->pev->takedamage ) return;
	if ( !FBitSet( pOther->pev->flags, FL_CLIENT|FL_MONSTER ) && !pOther->IsPushable() ) return;

	if ( IsMultiplayer() )
	{
		if ( pev->dmgtime > gpGlobals->time )
		{
			if ( gpGlobals->time != pev->dmg_take )
			{
				// too early to hurt again, and not same frame with a different entity
				if ( pOther->IsPlayer() )
				{
					int playerMask = 1 << (pOther->entindex() - 1);
					if ( pev->impulse & playerMask ) return;
					pev->impulse |= playerMask;
				}
				else return;
			}
		}
		else
		{
			pev->impulse = 0;
			if ( pOther->IsPlayer() )
			{
				int playerMask = 1 << (pOther->entindex() - 1);
				pev->impulse |= playerMask;
			}
		}
	}
	else if( pev->dmgtime > gpGlobals->time && gpGlobals->time != pev->dmg_take ) return;

	fldmg = pev->dmg * 0.5;	// 0.5 seconds worth of damage, pev->dmg is damage/second

	if ( fldmg < 0 ) pOther->TakeHealth( -fldmg, pev->button );
	else pOther->TakeDamage( pev, pev, fldmg, pev->button );

	pev->dmg_take = gpGlobals->time;
	pev->dmgtime = gpGlobals->time + 0.5;
}
	BOOL AddAmmo(CBaseEntity *pOther)
	{
		int iGive;

		if (IsMultiplayer())
		{
			// hand out more ammo per rocket in multiplayer.
			iGive = AMMO_RPGCLIP_GIVE * 2;
		}
		else
		{
			iGive = AMMO_RPGCLIP_GIVE;
		}
		if (pOther->GiveAmmo(iGive, "rockets", ROCKET_MAX_CARRY) != -1)
		{
			EMIT_SOUND(ENT(pev), CHAN_ITEM, "items/9mmclip1.wav", 1, ATTN_NORM);
			return TRUE;
		}
		return FALSE;
	}
Example #10
0
void CTriggerCamera :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
{
	if( pActivator && pActivator->IsPlayer( ))
	{
		// only at player
		m_hActivator = pActivator;
	}	
	else if( !IsMultiplayer( ))
	{
		m_hActivator = UTIL_PlayerByIndex( 1 );
	}		
	else
	{
		ALERT( at_warning, "%s: %s activator not player. Ignored.\n", STRING( pev->classname ), STRING( pev->targetname ));		
		return;
	}

	if ( useType == USE_TOGGLE )
	{
		if ( m_iState == STATE_OFF )
			useType = USE_ON;
		else useType = USE_OFF;
	}
	if ( useType == USE_ON )
	{
		TurnOn();
	}
	else if ( useType == USE_OFF )
	{
		TurnOff();
	}
	else if ( useType == USE_SHOWINFO )
	{
		ALERT( at_console, "======/Xash Debug System/======\n");
		ALERT( at_console, "classname: %s\n", STRING( pev->classname ));
		ALERT( at_console, "State: %s, Look at %s\n", GetStringForState( GetState()), pev->netname ? STRING( pev->netname ) : STRING( pev->targetname ));
		ALERT( at_console, "Speed: %g Camera target: %s\n", pev->speed, pTarget ? STRING(pTarget->pev->targetname) : "None" );
	}
}
Example #11
0
/*
=================
idCommonLocal::Frame
=================
*/
void idCommonLocal::Frame() {
	try {
		SCOPED_PROFILE_EVENT( "Common::Frame" );

		// This is the only place this is incremented
		idLib::frameNumber++;

		// allow changing SIMD usage on the fly
		if ( com_forceGenericSIMD.IsModified() ) {
			idSIMD::InitProcessor( "doom", com_forceGenericSIMD.GetBool() );
			com_forceGenericSIMD.ClearModified();
		}

		// Do the actual switch between Doom 3 and the classics here so
		// that things don't get confused in the middle of the frame.
		PerformGameSwitch();

		// pump all the events
		Sys_GenerateEvents();

		// write config file if anything changed
		WriteConfiguration(); 

		eventLoop->RunEventLoop();

		// Activate the shell if it's been requested
		if ( showShellRequested && game ) {
			game->Shell_Show( true );
			showShellRequested = false;
		}

		// if the console or another gui is down, we don't need to hold the mouse cursor
		bool chatting = false;
		if ( console->Active() || Dialog().IsDialogActive() || session->IsSystemUIShowing() || ( game && game->InhibitControls() && !IsPlayingDoomClassic() ) ) {
			Sys_GrabMouseCursor( false );
			usercmdGen->InhibitUsercmd( INHIBIT_SESSION, true );
			chatting = true;
		} else {
			Sys_GrabMouseCursor( true );
			usercmdGen->InhibitUsercmd( INHIBIT_SESSION, false );
		}

		const bool pauseGame = ( !mapSpawned || ( !IsMultiplayer() && ( Dialog().IsDialogPausing() || session->IsSystemUIShowing() || ( game && game->Shell_IsActive() ) ) ) ) && !IsPlayingDoomClassic();

		// save the screenshot and audio from the last draw if needed
		if ( aviCaptureMode ) {
			idStr name = va("demos/%s/%s_%05i.tga", aviDemoShortName.c_str(), aviDemoShortName.c_str(), aviDemoFrameCount++ );
			renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL );

			// remove any printed lines at the top before taking the screenshot
			console->ClearNotifyLines();

			// this will call Draw, possibly multiple times if com_aviDemoSamples is > 1
			renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL );
		}

		//--------------------------------------------
		// wait for the GPU to finish drawing
		//
		// It is imporant to minimize the time spent between this
		// section and the call to renderSystem->RenderCommandBuffers(),
		// because the GPU is completely idle.
		//--------------------------------------------
		// this should exit right after vsync, with the GPU idle and ready to draw
		// This may block if the GPU isn't finished renderng the previous frame.
		frameTiming.startSyncTime = Sys_Microseconds();
		const emptyCommand_t * renderCommands = NULL;
		if ( com_smp.GetBool() ) {
			renderCommands = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu );
		} else {
			// the GPU will stay idle through command generation for minimal
			// input latency
			renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu );
		}
		frameTiming.finishSyncTime = Sys_Microseconds();

		//--------------------------------------------
		// Determine how many game tics we are going to run,
		// now that the previous frame is completely finished.
		//
		// It is important that any waiting on the GPU be done
		// before this, or there will be a bad stuttering when
		// dropping frames for performance management.
		//--------------------------------------------

		// input:
		// thisFrameTime
		// com_noSleep
		// com_engineHz
		// com_fixedTic
		// com_deltaTimeClamp
		// IsMultiplayer
		//
		// in/out state:
		// gameFrame
		// gameTimeResidual
		// lastFrameTime
		// syncNextFrame
		//
		// Output:
		// numGameFrames

		// How many game frames to run
		int numGameFrames = 0;

		for(;;) {
			const int thisFrameTime = Sys_Milliseconds();
			static int lastFrameTime = thisFrameTime;	// initialized only the first time
			const int deltaMilliseconds = thisFrameTime - lastFrameTime;
			lastFrameTime = thisFrameTime;

			// if there was a large gap in time since the last frame, or the frame
			// rate is very very low, limit the number of frames we will run
			const int clampedDeltaMilliseconds = Min( deltaMilliseconds, com_deltaTimeClamp.GetInteger() );

			gameTimeResidual += clampedDeltaMilliseconds * timescale.GetFloat();

			// don't run any frames when paused
			if ( pauseGame ) {
				gameFrame++;
				gameTimeResidual = 0;
				break;
			}

			// debug cvar to force multiple game tics
			if ( com_fixedTic.GetInteger() > 0 ) {
				numGameFrames = com_fixedTic.GetInteger();
				gameFrame += numGameFrames;
				gameTimeResidual = 0;
				break;
			}

			if ( syncNextGameFrame ) {
				// don't sleep at all
				syncNextGameFrame = false;
				gameFrame++;
				numGameFrames++;
				gameTimeResidual = 0;
				break;
			}

			for ( ;; ) {
				// How much time to wait before running the next frame,
				// based on com_engineHz
				const int frameDelay = FRAME_TO_MSEC( gameFrame + 1 ) - FRAME_TO_MSEC( gameFrame );
				if ( gameTimeResidual < frameDelay ) {
					break;
				}
				gameTimeResidual -= frameDelay;
				gameFrame++;
				numGameFrames++;
				// if there is enough residual left, we may run additional frames
			}

			if ( numGameFrames > 0 ) {
				// ready to actually run them
				break;
			}

			// if we are vsyncing, we always want to run at least one game
			// frame and never sleep, which might happen due to scheduling issues
			// if we were just looking at real time.
			if ( com_noSleep.GetBool() ) {
				numGameFrames = 1;
				gameFrame += numGameFrames;
				gameTimeResidual = 0;
				break;
			}

			// not enough time has passed to run a frame, as might happen if
			// we don't have vsync on, or the monitor is running at 120hz while
			// com_engineHz is 60, so sleep a bit and check again
			Sys_Sleep( 0 );
		}

		//--------------------------------------------
		// It would be better to push as much of this as possible
		// either before or after the renderSystem->SwapCommandBuffers(),
		// because the GPU is completely idle.
		//--------------------------------------------

		// Update session and syncronize to the new session state after sleeping
		session->UpdateSignInManager();
		session->Pump();
		session->ProcessSnapAckQueue();

		if ( session->GetState() == idSession::LOADING ) {
			// If the session reports we should be loading a map, load it!
			ExecuteMapChange();
			mapSpawnData.savegameFile = NULL;
			mapSpawnData.persistentPlayerInfo.Clear();
			return;
		} else if ( session->GetState() != idSession::INGAME && mapSpawned ) {
			// If the game is running, but the session reports we are not in a game, disconnect
			// This happens when a server disconnects us or we sign out
			LeaveGame();
			return;
		}

		if ( mapSpawned && !pauseGame ) {
			if ( IsClient() ) {
				RunNetworkSnapshotFrame();
			}
		}

		ExecuteReliableMessages();

		// send frame and mouse events to active guis
		GuiFrameEvents();

		//--------------------------------------------
		// Prepare usercmds and kick off the game processing
		// in a background thread
		//--------------------------------------------

		// get the previous usercmd for bypassed head tracking transform
		const usercmd_t	previousCmd = usercmdGen->GetCurrentUsercmd();

		// build a new usercmd
		int deviceNum = session->GetSignInManager().GetMasterInputDevice();
		usercmdGen->BuildCurrentUsercmd( deviceNum );
		if ( deviceNum == -1 ) {
			for ( int i = 0; i < MAX_INPUT_DEVICES; i++ ) {
				Sys_PollJoystickInputEvents( i );
				Sys_EndJoystickInputEvents();
			}
		}
		if ( pauseGame ) {
			usercmdGen->Clear();
		}

		usercmd_t newCmd = usercmdGen->GetCurrentUsercmd();

		// Store server game time - don't let time go past last SS time in case we are extrapolating
		if ( IsClient() ) {
			newCmd.serverGameMilliseconds = std::min( Game()->GetServerGameTimeMs(), Game()->GetSSEndTime() );
		} else {
			newCmd.serverGameMilliseconds = Game()->GetServerGameTimeMs();
		}

		userCmdMgr.MakeReadPtrCurrentForPlayer( Game()->GetLocalClientNum() );

		// Stuff a copy of this userCmd for each game frame we are going to run.
		// Ideally, the usercmds would be built in another thread so you could
		// still get 60hz control accuracy when the game is running slower.
		for ( int i = 0 ; i < numGameFrames ; i++ ) {
			newCmd.clientGameMilliseconds = FRAME_TO_MSEC( gameFrame-numGameFrames+i+1 );
			userCmdMgr.PutUserCmdForPlayer( game->GetLocalClientNum(), newCmd );
		}

		// If we're in Doom or Doom 2, run tics and upload the new texture.
		if ( ( GetCurrentGame() == DOOM_CLASSIC || GetCurrentGame() == DOOM2_CLASSIC ) && !( Dialog().IsDialogPausing() || session->IsSystemUIShowing() ) ) {
			RunDoomClassicFrame();
		}
		
		// start the game / draw command generation thread going in the background
		gameReturn_t ret = gameThread.RunGameAndDraw( numGameFrames, userCmdMgr, IsClient(), gameFrame - numGameFrames );

		if ( !com_smp.GetBool() ) {
			// in non-smp mode, run the commands we just generated, instead of
			// frame-delayed ones from a background thread
			renderCommands = renderSystem->SwapCommandBuffers_FinishCommandBuffers();
		}

		//----------------------------------------
		// Run the render back end, getting the GPU busy with new commands
		// ASAP to minimize the pipeline bubble.
		//----------------------------------------
		frameTiming.startRenderTime = Sys_Microseconds();
		renderSystem->RenderCommandBuffers( renderCommands );
		if ( com_sleepRender.GetInteger() > 0 ) {
			// debug tool to test frame adaption
			Sys_Sleep( com_sleepRender.GetInteger() );
		}
		frameTiming.finishRenderTime = Sys_Microseconds();

		// make sure the game / draw thread has completed
		// This may block if the game is taking longer than the render back end
		gameThread.WaitForThread();

		// Send local usermds to the server.
		// This happens after the game frame has run so that prediction data is up to date.
		SendUsercmds( Game()->GetLocalClientNum() );

		// Now that we have an updated game frame, we can send out new snapshots to our clients
		session->Pump(); // Pump to get updated usercmds to relay
		SendSnapshots();

		// Render the sound system using the latest commands from the game thread
		if ( pauseGame ) {
			soundWorld->Pause();
			soundSystem->SetPlayingSoundWorld( menuSoundWorld );
		} else {
			soundWorld->UnPause();
			soundSystem->SetPlayingSoundWorld( soundWorld );
		}
		soundSystem->Render();

		// process the game return for map changes, etc
		ProcessGameReturn( ret );

		idLobbyBase & lobby = session->GetActivePlatformLobbyBase();
		if ( lobby.HasActivePeers() ) {
			if ( net_drawDebugHud.GetInteger() == 1 ) {
				lobby.DrawDebugNetworkHUD();
			}
			if ( net_drawDebugHud.GetInteger() == 2 ) {
				lobby.DrawDebugNetworkHUD2();
			}
			lobby.DrawDebugNetworkHUD_ServerSnapshotMetrics( net_drawDebugHud.GetInteger() == 3 );
		}

		// report timing information
		if ( com_speeds.GetBool() ) {
			static int lastTime = Sys_Milliseconds();
			int	nowTime = Sys_Milliseconds();
			int	com_frameMsec = nowTime - lastTime;
			lastTime = nowTime;
			Printf( "frame:%d all:%3d gfr:%3d rf:%3lld bk:%3lld\n", idLib::frameNumber, com_frameMsec, time_gameFrame, time_frontend / 1000, time_backend / 1000 );
			time_gameFrame = 0;
			time_gameDraw = 0;
		}

		// the FPU stack better be empty at this point or some bad code or compiler bug left values on the stack
		if ( !Sys_FPU_StackIsEmpty() ) {
			Printf( Sys_FPU_GetState() );
			FatalError( "idCommon::Frame: the FPU stack is not empty at the end of the frame\n" );
		}

		mainFrameTiming = frameTiming;

		session->GetSaveGameManager().Pump();
	} catch( idException & ) {
		return;			// an ERP_DROP was thrown
	}
}
Example #12
0
void GenerateFog()
{
    int screen_x = *bw::screen_pos_x_tiles;
    if (screen_x != 0)
        screen_x--;
    int screen_y = *bw::screen_pos_y_tiles;
    if (screen_y != 0)
        screen_y--;
    uint32_t *flags = (*bw::map_tile_flags) + screen_y * *bw::map_width_tiles + screen_x;
    uint32_t *orig_flags = flags;
    uint8_t *pos = *bw::fog_arr1;
    int shown_value = *bw::fog_variance_amount;
    int fow_value = shown_value / 2;

    int y_pos = screen_y;
    for (int i = 0; i < 0x11; i++)
    {
        int x_pos = *bw::screen_pos_x_tiles - 1;
        flags = orig_flags;
        for (int i = 0; i < 0x18; i++)
        {
            // Obviously people can just remove multiplayer check if they wish
            // Bw had nice vision-based sync but it does not work with dynamically allocated sprites
            if (all_visions && !IsMultiplayer())
            {
                if ((0xff00 & flags[0]) == 0xff00)
                    *pos = 0;
                else if ((0xff & flags[0]) == 0xff)
                    *pos = fow_value;
                else
                    *pos = shown_value;
            }
            else if (IsReplay())
            {
                if (*bw::replay_show_whole_map)
                    *pos = shown_value;
                else if (!((*bw::replay_visions << 8) & ~flags[0]))
                    *pos = 0;
                else if (!(*bw::replay_visions & ~flags[0]))
                    *pos = fow_value;
                else
                    *pos = shown_value;
            }
            else
            {
                if (*bw::player_exploration_visions & flags[0])
                    *pos = 0;
                else if (*bw::player_visions & flags[0])
                    *pos = fow_value;
                else
                    *pos = shown_value;
            }
            if (x_pos < *bw::map_width_tiles - 1 && x_pos >= 0)
                flags++;
            x_pos++;
            pos++;
        }
        if (y_pos < *bw::map_height_tiles - 1 && y_pos >= 0)
            orig_flags += *bw::map_width_tiles;
        y_pos++;
    }

    // Blend fog
    // Screen is 0x18 x 0x11 tiles
    // Well every border has 1 nonvisible tile, it is only used for blending?
    pos = *bw::fog_arr1 + 0x18 + 0x1;
    uint8_t *out = *bw::fog_arr2 + 0x18 + 0x1;
    for (int i = 0; i < 0x11 - 2; i++)
    {
        for (int i = 0; i < 0x18 - 2; i++)
        {
            int val = pos[0] * 2;
            val = (val + pos[-1] + pos[1] + pos[-0x18] + pos[0x18]) * 2;
            val = (val + pos[-0x17] + pos[0x17] + pos[-0x19] + pos[0x19]) / 16;
            *out = val;
            pos++;
            out++;
        }
        pos += 2;
        out += 2;
    }
}
Example #13
0
/*
===============
idCommonLocal::ExecuteMapChange

Performs the initialization of a game based on session match parameters, used for both single
player and multiplayer, but not for renderDemos, which don't create a game at all.
Exits with mapSpawned = true
===============
*/
void idCommonLocal::ExecuteMapChange() {
	if ( session->GetState() != idSession::LOADING ) {
		idLib::Warning( "Session state is not LOADING in ExecuteMapChange" );
		return;
	}

	// Clear all dialogs before beginning the load
	common->Dialog().ClearDialogs( true );
	
	// Remember the current load ID.
	// This is so we can tell if we had a new loadmap request from within an existing loadmap call
	const int cachedLoadingID = session->GetLoadingID();

	const idMatchParameters & matchParameters = session->GetActingGameStateLobbyBase().GetMatchParms();

	if ( matchParameters.numSlots <= 0 ) {
		idLib::Warning( "numSlots <= 0 in ExecuteMapChange" );
		return;
	}

	insideExecuteMapChange = true;

	common->Printf( "--------- Execute Map Change ---------\n" );
	common->Printf( "Map: %s\n", matchParameters.mapName.c_str() );

	// ensure that r_znear is reset to the default value
	// this fixes issues with the projection matrix getting messed up when switching maps or loading a saved game
	// while an in-game cinematic is playing.
	cvarSystem->SetCVarFloat( "r_znear", 1.0f );

	// reset all cheat cvars for a multiplayer game
	if ( IsMultiplayer() ) {
		cvarSystem->ResetFlaggedVariables( CVAR_CHEAT );
	}

	int start = Sys_Milliseconds();

	for ( int i = 0; i < MAX_INPUT_DEVICES; i++ ) {
		Sys_SetRumble( i, 0, 0 );
	}

	// close console and remove any prints from the notify lines
	console->Close();

	// clear all menu sounds
	soundWorld->Pause();
	menuSoundWorld->ClearAllSoundEmitters();
	soundSystem->SetPlayingSoundWorld( menuSoundWorld );
	soundSystem->Render();

	// extract the map name from serverinfo
	currentMapName = matchParameters.mapName;
	currentMapName.StripFileExtension();

	idStrStatic< MAX_OSPATH > fullMapName = "maps/";
	fullMapName += currentMapName;
	fullMapName.SetFileExtension( "map" );

	if ( mapSpawnData.savegameFile ) {
		fileSystem->BeginLevelLoad( currentMapName, NULL, 0 );
	} else {
		fileSystem->BeginLevelLoad( currentMapName, saveFile.GetDataPtr(), saveFile.GetAllocated() );
	}

	// capture the current screen and start a wipe
	// immediately complete the wipe to fade out the level transition
	// run the wipe to completion
	StartWipe( "wipeMaterial", true );
	CompleteWipe();

	int sm = Sys_Milliseconds();
	// shut down the existing game if it is running
	UnloadMap();
	int ms = Sys_Milliseconds() - sm;
	common->Printf( "%6d msec to unload map\n", ms );

	// Free media from previous level and
	// note which media we are going to need to load
	sm = Sys_Milliseconds();
	renderSystem->BeginLevelLoad();
	soundSystem->BeginLevelLoad();
	declManager->BeginLevelLoad();
	uiManager->BeginLevelLoad();
	ms = Sys_Milliseconds() - sm;
	common->Printf( "%6d msec to free assets\n", ms );

	//Sys_DumpMemory( true );

	// load / program a gui to stay up on the screen while loading
	// set the loading gui that we will wipe to
	bool hellMap = false;
	LoadLoadingGui( currentMapName, hellMap );

	// Stop rendering the wipe
	ClearWipe();


	if ( fileSystem->UsingResourceFiles() ) {
		idStrStatic< MAX_OSPATH > manifestName = currentMapName;
		manifestName.Replace( "game/", "maps/" );
		manifestName.Replace( "/mp/", "/" );
		manifestName += ".preload";
		idPreloadManifest manifest;
		manifest.LoadManifest( manifestName );
		renderSystem->Preload( manifest, currentMapName );
		soundSystem->Preload( manifest );
		game->Preload( manifest );
	}

	if ( common->IsMultiplayer() ) {
		// In multiplayer, make sure the player is either 60Hz or 120Hz
		// to avoid potential issues.
		const float mpEngineHz = ( com_engineHz.GetFloat() < 90.0f ) ? 60.0f : 120.0f;
		com_engineHz_denominator = 100LL * mpEngineHz;
		com_engineHz_latched = mpEngineHz;
	} else {
		// allow com_engineHz to be changed between map loads
		com_engineHz_denominator = 100LL * com_engineHz.GetFloat();
		com_engineHz_latched = com_engineHz.GetFloat();
	}

	// note any warning prints that happen during the load process
	common->ClearWarnings( currentMapName );

	// release the mouse cursor
	// before we do this potentially long operation
	Sys_GrabMouseCursor( false );

	// let the renderSystem load all the geometry
	if ( !renderWorld->InitFromMap( fullMapName ) ) {
		common->Error( "couldn't load %s", fullMapName.c_str() );
	}

	// for the synchronous networking we needed to roll the angles over from
	// level to level, but now we can just clear everything
	usercmdGen->InitForNewMap();

	// load and spawn all other entities ( from a savegame possibly )
	if ( mapSpawnData.savegameFile ) {
		if ( !game->InitFromSaveGame( fullMapName, renderWorld, soundWorld, mapSpawnData.savegameFile, mapSpawnData.stringTableFile, mapSpawnData.savegameVersion ) ) {
			// If the loadgame failed, end the session, which will force us to go back to the main menu
			session->QuitMatchToTitle();
		}
	} else {
		if ( !IsMultiplayer() ) {
			assert( game->GetLocalClientNum() == 0 );
			assert( matchParameters.gameMode == GAME_MODE_SINGLEPLAYER );
			assert( matchParameters.gameMap == GAME_MAP_SINGLEPLAYER );
			game->SetPersistentPlayerInfo( 0, mapSpawnData.persistentPlayerInfo );
		}
		game->SetServerInfo( matchParameters.serverInfo );
		game->InitFromNewMap( fullMapName, renderWorld, soundWorld, matchParameters.gameMode, Sys_Milliseconds() );
	}

	game->Shell_CreateMenu( true );

	// Reset some values important to multiplayer
	ResetNetworkingState();

	// If the session state is not loading here, something went wrong.
	if ( session->GetState() == idSession::LOADING && session->GetLoadingID() == cachedLoadingID ) {
		// Notify session we are done loading
		session->LoadingFinished();

		while ( session->GetState() == idSession::LOADING ) {
			Sys_GenerateEvents();
			session->UpdateSignInManager();
			session->Pump();
			Sys_Sleep( 10 );
		}
	}

	if ( !mapSpawnData.savegameFile ) {
		// run a single frame to catch any resources that are referenced by events posted in spawn
		idUserCmdMgr emptyCommandManager;
		gameReturn_t emptyGameReturn;
		for ( int playerIndex = 0; playerIndex < MAX_PLAYERS; ++playerIndex ) {
			emptyCommandManager.PutUserCmdForPlayer( playerIndex, usercmd_t() );
		}
		if ( IsClient() ) {
			game->ClientRunFrame( emptyCommandManager, false, emptyGameReturn );
		} else {
			game->RunFrame( emptyCommandManager, emptyGameReturn );
		}
	}

	renderSystem->EndLevelLoad();
	soundSystem->EndLevelLoad();
	declManager->EndLevelLoad();
	uiManager->EndLevelLoad( currentMapName );
	fileSystem->EndLevelLoad();

	if ( !mapSpawnData.savegameFile && !IsMultiplayer() ) {
		common->Printf( "----- Running initial game frames -----\n" );

		// In single player, run a bunch of frames to make sure ragdolls are settled
		idUserCmdMgr emptyCommandManager;
		gameReturn_t emptyGameReturn;
		for ( int i = 0; i < 100; i++ ) {
			for ( int playerIndex = 0; playerIndex < MAX_PLAYERS; ++playerIndex ) {
				emptyCommandManager.PutUserCmdForPlayer( playerIndex, usercmd_t() );
			}
			game->RunFrame( emptyCommandManager, emptyGameReturn );
		}

		// kick off an auto-save of the game (so we can always continue in this map if we die before hitting an autosave)
		common->Printf( "----- Saving Game -----\n" );
		SaveGame( "autosave" );
	}

	common->Printf( "----- Generating Interactions -----\n" );

	// let the renderSystem generate interactions now that everything is spawned
	renderWorld->GenerateAllInteractions();

	{
		int vertexMemUsedKB = vertexCache.staticData.vertexMemUsed.GetValue() / 1024;
		int indexMemUsedKB = vertexCache.staticData.indexMemUsed.GetValue() / 1024;
		idLib::Printf( "Used %dkb of static vertex memory (%d%%)\n", vertexMemUsedKB, vertexMemUsedKB * 100 / ( STATIC_VERTEX_MEMORY / 1024 ) );
		idLib::Printf( "Used %dkb of static index memory (%d%%)\n", indexMemUsedKB, indexMemUsedKB * 100 / ( STATIC_INDEX_MEMORY / 1024 ) );
	}

	if ( common->JapaneseCensorship() ) {
		if ( currentMapName.Icmp( "game/mp/d3xpdm3" ) == 0 ) {
			const idMaterial * gizpool2 = declManager->FindMaterial( "textures/hell/gizpool2" );
			idMaterial * chiglass1bluex = const_cast<idMaterial *>( declManager->FindMaterial( "textures/sfx/chiglass1bluex" ) );
			idTempArray<char> text( gizpool2->GetTextLength() );
			gizpool2->GetText( text.Ptr() );
			chiglass1bluex->Parse( text.Ptr(), text.Num(), false );
		}
	}

	common->PrintWarnings();

	session->Pump();

	if ( session->GetState() != idSession::INGAME ) {
		// Something went wrong, don't process stale reliables that have been queued up.
		reliableQueue.Clear();
	}

	usercmdGen->Clear();

	// remove any prints from the notify lines
	console->ClearNotifyLines();

	Sys_SetPhysicalWorkMemory( -1, -1 );

	// at this point we should be done with the loading gui so we kill it
	delete loadGUI;
	loadGUI = NULL;


	// capture the current screen and start a wipe
	StartWipe( "wipe2Material" );

	// we are valid for game draws now
	insideExecuteMapChange = false;
	mapSpawned = true;
	Sys_ClearEvents();


	int	msec = Sys_Milliseconds() - start;
	common->Printf( "%6d msec to load %s\n", msec, currentMapName.c_str() );
	//Sys_DumpMemory( false );	

	// Issue a render at the very end of the load process to update soundTime before the first frame
	soundSystem->Render();
}
Example #14
0
/*
===============
idCommonLocal::SaveGame
===============
*/
bool idCommonLocal::SaveGame( const char * saveName ) {
	if ( pipelineFile != NULL ) {
		// We're already in the middle of a save. Leave us alone.
		return false;
	}

	if ( com_disableAllSaves.GetBool() || ( com_disableAutoSaves.GetBool() && ( idStr::Icmp( saveName, "autosave" ) == 0 ) ) ) {
		return false;
	}

	if ( IsMultiplayer() ) {
		common->Printf( "Can't save during net play.\n" );
		return false;
	}

	if (mapSpawnData.savegameFile != NULL ) {
		return false;
	}

	const idDict & persistentPlayerInfo = game->GetPersistentPlayerInfo( 0 );
	if ( persistentPlayerInfo.GetInt( "health" ) <= 0 ) {
		common->Printf( "You must be alive to save the game\n" );
		return false;
	}

	soundWorld->Pause();
	soundSystem->SetPlayingSoundWorld( menuSoundWorld );
	soundSystem->Render();

	Dialog().ShowSaveIndicator( true );
	if ( insideExecuteMapChange ) {
		UpdateLevelLoadPacifier();
	} else {
		// Heremake sure we pump the gui enough times to show the 'saving' dialog
		const bool captureToImage = false;
		for ( int i = 0; i < NumScreenUpdatesToShowDialog; ++i ) {
			UpdateScreen( captureToImage );
		}
		renderSystem->BeginAutomaticBackgroundSwaps( AUTORENDER_DIALOGICON );
	}

	// Make sure the file is writable and the contents are cleared out (Set to write from the start of file)
	saveFile.MakeWritable();
	saveFile.Clear( false );
	stringsFile.MakeWritable();
	stringsFile.Clear( false );

	// Setup the save pipeline
	pipelineFile = new (TAG_SAVEGAMES) idFile_SaveGamePipelined();
	pipelineFile->OpenForWriting( &saveFile );

	// Write SaveGame Header: 
	// Game Name / Version / Map Name / Persistant Player Info

	// game
	const char *gamename = GAME_NAME;
	saveFile.WriteString( gamename );

	// map
	saveFile.WriteString( currentMapName );

	saveFile.WriteBool( consoleUsed );

	game->GetServerInfo().WriteToFileHandle( &saveFile );

	// let the game save its state
	game->SaveGame( pipelineFile, &stringsFile );

	pipelineFile->Finish();

	idSaveGameDetails gameDetails;
	game->GetSaveGameDetails( gameDetails );

	gameDetails.descriptors.Set( SAVEGAME_DETAIL_FIELD_LANGUAGE, sys_lang.GetString() );
	gameDetails.descriptors.SetInt( SAVEGAME_DETAIL_FIELD_CHECKSUM, (int)gameDetails.descriptors.Checksum() );

	gameDetails.slotName = saveName;
	ScrubSaveGameFileName( gameDetails.slotName );

	saveFileEntryList_t files;
	files.Append( &stringsFile );
	files.Append( &saveFile );

	session->SaveGameSync( gameDetails.slotName, files, gameDetails );

	if ( !insideExecuteMapChange ) {
		renderSystem->EndAutomaticBackgroundSwaps();
	}

	syncNextGameFrame = true;

	return true;
}
Example #15
0
static void Command_GameSpeed(uint8_t *data)
{
    int speed = data[1];
    if (!IsMultiplayer() && speed <= 6)
        *bw::game_speed = speed;
}
/*
===============
idCommonLocal::IsServer
===============
*/
bool idCommonLocal::IsServer() {
    return IsMultiplayer() && session->GetActingGameStateLobbyBase().IsHost();
}
/*
===============
idCommonLocal::IsClient
===============
*/
bool idCommonLocal::IsClient() {
    return IsMultiplayer() && session->GetActingGameStateLobbyBase().IsPeer();
}
Example #18
0
/*
===============
idCommonLocal::LoadGame
===============
*/
bool idCommonLocal::LoadGame( const char * saveName ) { 
	if ( IsMultiplayer() ) {
		common->Printf( "Can't load during net play.\n" );
		if ( wipeForced ) {
			ClearWipe();
		}
		return false;
	}

	if ( GetCurrentGame() != DOOM3_BFG ) {
		return false;
	}

	if ( session->GetSignInManager().GetMasterLocalUser() == NULL ) {
		return false;
	}
	if (mapSpawnData.savegameFile != NULL ) {
		return false;
	}

	bool found = false;
	const saveGameDetailsList_t & sgdl = session->GetSaveGameManager().GetEnumeratedSavegames();
	for ( int i = 0; i < sgdl.Num(); i++ ) {
		if ( sgdl[i].slotName == saveName ) {
			if ( sgdl[i].GetLanguage() != sys_lang.GetString() ) {
				idStaticList< idSWFScriptFunction *, 4 > callbacks;
				idStaticList< idStrId, 4 > optionText;
				optionText.Append( idStrId( "#str_swf_continue" ) );
				idStrStatic<256> langName = "#str_lang_" + sgdl[i].GetLanguage();
				idStrStatic<256> msg;
				msg.Format( idLocalization::GetString( "#str_dlg_wrong_language" ), idLocalization::GetString( langName ) );
				Dialog().AddDynamicDialog( GDM_SAVEGAME_WRONG_LANGUAGE, callbacks, optionText, true, msg, false, true );
				if ( wipeForced ) {
					ClearWipe();
				}
				return false;
			}
			found = true;
			break;
		}
	}
	if ( !found ) {
		common->Printf( "Could not find save '%s'\n", saveName );
		if ( wipeForced ) {
			ClearWipe();
		}
		return false;
	}

	mapSpawnData.savegameFile = &saveFile;
	mapSpawnData.stringTableFile = &stringsFile;

	saveFileEntryList_t files;
	files.Append( mapSpawnData.stringTableFile );
	files.Append( mapSpawnData.savegameFile );

	idStr slotName = saveName;
	ScrubSaveGameFileName( slotName );
	saveFile.Clear( false );
	stringsFile.Clear( false );

	saveGameHandle_t loadGameHandle = session->LoadGameSync( slotName, files );
	if ( loadGameHandle != 0 ) {
		return true;
	}
	mapSpawnData.savegameFile = NULL;
	if ( wipeForced ) {
		ClearWipe();
	}
	return false;
}