//============================================================================= // Copyright (C) 2002 Radical Entertainment Ltd. All rights reserved. // // File: // // Description: Implement GameplayContext // // History: 21/05/2002 + Created -- NAME // //============================================================================= //======================================== // System Includes //======================================== // Foundation Tech #include #include #include //======================================== // Project Includes //======================================== #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef RAD_WIN32 #include #endif //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //****************************************************************************** // // Global Data, Local Data, Local Classes // //****************************************************************************** // Static pointer to instance of singleton. GameplayContext* GameplayContext::spInstance = NULL; //****************************************************************************** // // Public Member Functions // //****************************************************************************** //============================================================================== // GameplayContext::GetInstance //============================================================================== // // Description: - Access point for the GameplayContext singleton. // - Creates the GameplayContext if needed. // // Parameters: None. // // Return: Pointer to the GameplayContext. // // Constraints: This is a singleton so only one instance is allowed. // //============================================================================== GameplayContext* GameplayContext::GetInstance() { if( spInstance == NULL ) { spInstance = new(GMA_PERSISTENT) GameplayContext; rAssert( spInstance ); } return spInstance; } //============================================================================== // GameplayContext::GameplayContext //============================================================================== // Description: Constructor. // // Parameters: None. // // Return: N/A. // //============================================================================== GameplayContext::GameplayContext() : m_PausedAllButPresentation( false ), mSlowMoHack( false ) { #ifdef DEBUGWATCH radDbgWatchAddUnsignedInt( &mDebugPhysTiming, "Debug Phys micros", "GameplayContext", NULL, NULL ); radDbgWatchAddUnsignedInt( &mDebugTimeDelta, "Debug dT micros", "GameplayContext", NULL, NULL ); radDbgWatchAddUnsignedInt( &mDebugOnUpdateDT, "Gameplay dT micros", "GameplayContext", NULL, NULL ); radDbgWatchAddBoolean(&mSlowMoHack, "Slow Mo Hack", "GameplayContext", NULL, NULL); #endif } //============================================================================== // GameplayContext::~GameplayContext //============================================================================== // Description: Destructor. // // Parameters: None. // // Return: N/A. // //============================================================================== GameplayContext::~GameplayContext() { #ifdef DEBUGWATCH radDbgWatchDelete(&mDebugPhysTiming); radDbgWatchDelete(&mDebugTimeDelta); radDbgWatchDelete(&mDebugOnUpdateDT); radDbgWatchDelete(&mSlowMoHack); #endif } //****************************************************************************** // // Private Member Functions // //****************************************************************************** //============================================================================= // GameplayContext::OnStart //============================================================================= // Description: Comment // // Parameters: ( ContextEnum previousContext ) // // Return: void // //============================================================================= void GameplayContext::OnStart( ContextEnum previousContext ) { // Common to all playing contexts. // PlayingContext::OnStart( previousContext ); MEMTRACK_PUSH_FLAG( "Gameplay" ); // do gameplay initializations only if previous context was loading context if( previousContext == CONTEXT_LOADING_GAMEPLAY ) { // RenderManager // RenderManager* rm = GetRenderManager(); RenderLayer* rl = rm->mpLayer( RenderEnums::LevelSlot ); rAssert( rl ); #ifdef DEBUGWATCH // bootstrap vehicleai renderer VehicleAIRender::GetVehicleAIRender(); #endif // Set up cameras // unsigned int iNumPlayers = GetGameplayManager()->GetNumPlayers(); rl->SetNumViews( iNumPlayers ); rl->SetUpViewCam(); p3d::inventory->SelectSection("Default"); tLightGroup* sun = p3d::find("sun"); rAssert( sun ); rm->SetLevelLayerLights( sun ); float aspect = p3d::display->IsWidescreen() ? (16.0f / 9.0f) : (4.0f / 3.0f); if( iNumPlayers == 2 ) { aspect = 4.0f / 1.5f; } for( unsigned int view = 0; view < iNumPlayers; view++ ) { tPointCamera* cam = static_cast( rl->pCam( view ) ); rAssert( dynamic_cast ( cam ) != NULL ); rAssert( cam ); SuperCamCentral* scc = GetSuperCamManager()->GetSCC( view ); rAssert( scc ); scc->SetCamera( cam ); FollowCam* fc = new FollowCam( FollowCam::FOLLOW_NEAR ); fc->SetAspect( aspect ); fc->CopyToData(); scc->RegisterSuperCam( fc ); fc = new FollowCam( FollowCam::FOLLOW_FAR ); fc->SetAspect( aspect ); fc->CopyToData(); scc->RegisterSuperCam( fc ); SuperCam* sc = new BumperCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new ChaseCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new KullCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new DebugCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new TrackerCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new WalkerCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new ComedyCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new WrecklessCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new ConversationCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new ReverseCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new AnimatedCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); sc = new RelativeAnimatedCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); // sc = new FirstPersonCam(); // sc->SetAspect( aspect ); // scc->RegisterSuperCam( sc ); #ifdef RAD_WIN32 sc = new PCCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); #endif #if !defined(FINAL) && defined(RAD_XBOX) sc = new SnapshotCam(); sc->SetAspect( aspect ); scc->RegisterSuperCam( sc ); #endif } // Boot strap the AvatarManager. // GetAvatarManager( )->EnterGame( ); GetActionButtonManager( )->EnterGame( ); TrafficManager::GetInstance()->Init(); PedestrianManager::GetInstance()->Init(); // Prepare the manager to start gameplay // //GetGameplayManager()->Reset(); #ifdef RAD_DEMO GetGameplayManager()->ResetIdleTime(); #endif // Start up GUI in-game manager GetGuiSystem()->HandleMessage( GUI_MSG_RUN_INGAME ); // register GUI user input handler for active players only // int activeControllerIDs = 0; for( int i = 0; i < MAX_PLAYERS; i++ ) { int controllerID = GetInputManager()->GetControllerIDforPlayer( i ); if( controllerID != -1 ) { activeControllerIDs |= (1 << controllerID); } } GetGuiSystem()->RegisterUserInputHandlers( activeControllerIDs ); // Tell GameData Manager that game has been started // GetGameDataManager()->SetGameLoaded(); //Set up the sorting of the intersections and stuff. RoadManager::GetInstance()->CreateRoadNetwork(); //Find skid mark shaders in the inventory and set proper values SkidMarkGenerator::InitShaders(); GetSkidmarkManager()->Init(); // // Notify the sound system of gameplay start. This has been moved after // the GUI startup above, since that leads to a mission reset, which causes // character position in or out of the car to be decided, which the sound // system uses to determine which sounds to start playing. // SoundManager::GetInstance()->OnGameplayStart(); GetInteriorManager()->OnGameplayStart(); GetHitnRunManager()->ResetState(); //tick character manager once, to get state system and choreo started GetCharacterManager()->PreSimUpdate( 0.0001f ); GetCharacterManager()->PreSubstepUpdate( 0.0001f ); GetCharacterManager()->Update( 0.0001f ); GetCharacterManager()->PostSubstepUpdate( 0.0001f ); GetCharacterManager()->PostSimUpdate( 0.0001f ); } GetPresentationManager()->OnGameplayStart(); HeapMgr()->ResetArtStats(); GetEventManager()->TriggerEvent( EVENT_LEVEL_START ); if( previousContext != CONTEXT_PAUSE ) { AnimatedCam::CheckPendingCameraSwitch(); } for( int view = 0; view < GetGameplayManager()->GetNumPlayers(); view++ ) { SuperCamCentral* scc = GetSuperCamManager()->GetSCC( view ); scc->SetIsInitialCamera(true); } GetGameplayManager()->Update( 0 ); GetTriggerVolumeTracker()->Update( 0 ); } //============================================================================= // GameplayContext::OnStop //============================================================================= // Description: Comment // // Parameters: ( ContextEnum nextContext ) // // Return: void // //============================================================================= void GameplayContext::OnStop( ContextEnum nextContext ) { GetPresentationManager()->OnGameplayStop(); // turn off controller rumble, to comply w/ TCR/TRC standards // GetInputManager()->ToggleRumble( false ); // Common to all playing contexts. // PlayingContext::OnStop( nextContext ); } //============================================================================= // GameplayContext::OnUpdate //============================================================================= // Description: Comment // // Parameters: ( unsigned int elapsedTime ) // // Return: void // //============================================================================= void GameplayContext::OnUpdate( unsigned int elapsedTime ) { #ifdef DEBUGWATCH mDebugOnUpdateDT = radTimeGetMicroseconds(); #endif #ifndef FINAL if( CommandLineOptions::Get( CLO_PRINT_FRAMERATE ) ) { // // Merasure the time taken to render frames 100-500 // const unsigned int startFrame = 200; const unsigned int endFrame = 600; static unsigned int count = 0; ++count; static unsigned int totalTime = 0; totalTime += elapsedTime; if( count == startFrame ) { totalTime = 0; } if( count == endFrame ) { const unsigned int frames = endFrame - startFrame; float msPerFrame = totalTime / static_cast< float >( frames ); rReleasePrintf( "====================================\n" ); rReleasePrintf( "%d frames rendered in %dms\n", frames, totalTime ); rReleasePrintf( "%fms per frame\n", msPerFrame ); rReleasePrintf( "====================================\n" ); } } static int frameCount = 60; frameCount--; if( frameCount == 0 ) { HeapMgr()->ResetArtStats(); } #endif // hack for yousuf if( mSlowMoHack ) { //elapsedTime = 1; elapsedTime = 2; } if( !m_PausedAllButPresentation ) { float timeins = (float)(elapsedTime) / 1000.0f; BEGIN_PROFILE("GameplayManager"); if ( m_state != S_SUSPENDED ) { GetGameplayManager()->Update( elapsedTime ); } END_PROFILE("GameplayManager"); GetAvatarManager()->Update( timeins ); GetFootprintManager()->Update( elapsedTime ); GetCharacterManager()->GarbageCollect( ); BEGIN_PROFILE( "Update Particles" ); GetParticleManager()->Update( elapsedTime ); GetBreakablesManager()->Update( elapsedTime ); GetAnimEntityDSGManager()->Update( elapsedTime ); END_PROFILE( "Update Particles" ); #ifdef DEBUGWATCH unsigned int t0 = radTimeGetMicroseconds(); #endif BEGIN_PROFILE("WorldPhysics"); GetWorldPhysicsManager()->Update(elapsedTime); END_PROFILE("WorldPhysics"); // ordering is important. Unless other parts of code change, we must call // this before WorldPhysManager::Update() because PedestrianManager // sets the flags for all characters to be updated in WorldPhys Update PedestrianManager::GetInstance()->Update( elapsedTime ); #ifdef DEBUGWATCH mDebugTimeDelta = elapsedTime; mDebugPhysTiming = radTimeGetMicroseconds()-t0 ; #endif BEGIN_PROFILE("TriggerVolumeTracker"); GetTriggerVolumeTracker()->Update( elapsedTime ); END_PROFILE("TriggerVolumeTracker"); BEGIN_PROFILE("TrafficManager"); TrafficManager::GetInstance()->Update( elapsedTime ); END_PROFILE("TrafficManager"); BEGIN_PROFILE("ActorManager"); ActorManager::GetInstance()->Update( elapsedTime ); END_PROFILE("ActorManager"); BEGIN_PROFILE("InteriorManager"); GetInteriorManager()->Update( elapsedTime ); END_PROFILE("InteriorManager"); BEGIN_PROFILE("SkidmarkManager"); GetSkidmarkManager()->Update( elapsedTime ); END_PROFILE("SkidmarkManager"); BEGIN_PROFILE( "CoinManager" ); GetCoinManager()->Update( elapsedTime ); GetSparkleManager()->Update( elapsedTime ); END_PROFILE( "CoinManager" ); BEGIN_PROFILE( "HitnRunManager" ); GetHitnRunManager()->Update( elapsedTime ); END_PROFILE( "HitnRunManager" ); } #ifdef RAD_DEMO GetGameplayManager()->UpdateIdleTime( elapsedTime ); #endif BEGIN_PROFILE("PresentationManager"); GetPresentationManager()->Update( elapsedTime ); END_PROFILE("PresentationManager"); // Common to all playing contexts. // PlayingContext::OnUpdate( elapsedTime ); #ifdef DEBUGWATCH mDebugOnUpdateDT = radTimeGetMicroseconds()-mDebugOnUpdateDT; #endif } //============================================================================= // GameplayContext::OnSuspend //============================================================================= // Description: Comment // // Parameters: () // // Return: void // //============================================================================= void GameplayContext::OnSuspend() { // Common to all playing contexts. // PlayingContext::OnSuspend(); } //============================================================================= // GameplayContext::OnResume //============================================================================= // Description: Comment // // Parameters: () // // Return: void // //============================================================================= void GameplayContext::OnResume() { // Common to all playing contexts. // PlayingContext::OnResume(); } //============================================================================= // GameplayContext::PauseAllButPresentation //============================================================================= // Description: Comment // // Parameters: () // // Return: void // //============================================================================= void GameplayContext::PauseAllButPresentation( const bool pause ) { m_PausedAllButPresentation = pause; }